Issue 121: converted all modules to sync/asyc

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2293 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-11-15 23:16:38 +00:00
parent 2285f36bd3
commit bc238bc507
280 changed files with 6968 additions and 3920 deletions

View File

@ -0,0 +1,198 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.atmosonline.saas;
import java.net.URI;
import java.util.concurrent.Future;
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.atmosonline.saas.binders.BindAtmosObjectToEntityAndMetadataToHeaders;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.SystemMetadata;
import org.jclouds.atmosonline.saas.domain.UserMetadata;
import org.jclouds.atmosonline.saas.filters.SignRequest;
import org.jclouds.atmosonline.saas.functions.AtmosObjectName;
import org.jclouds.atmosonline.saas.functions.ParseDirectoryListFromContentAndHeaders;
import org.jclouds.atmosonline.saas.functions.ParseObjectFromHeadersAndHttpContent;
import org.jclouds.atmosonline.saas.functions.ParseSystemMetadataFromHeaders;
import org.jclouds.atmosonline.saas.functions.ReturnEndpointIfAlreadyExists;
import org.jclouds.atmosonline.saas.options.ListOptions;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.http.options.GetOptions;
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;
/**
* Provides asynchronous access to EMC Atmos Online Storage resources via their REST API.
* <p/>
*
* @see AtmosStorageClient
* @see <a href="https://community.emc.com/community/labs/atmos_online" />
* @author Adrian Cole
*/
@Endpoint(AtmosStorage.class)
@RequestFilters(SignRequest.class)
@SkipEncoding( { '/' })
public interface AtmosStorageAsyncClient {
AtmosObject newObject();
/**
* @see AtmosStorageClient#listDirectories
*/
@GET
@Path("/rest/namespace")
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@Consumes(MediaType.TEXT_XML)
Future<? extends BoundedSortedSet<? extends DirectoryEntry>> listDirectories(
ListOptions... options);
/**
* @see AtmosStorageClient#listDirectory
*/
@GET
@Path("/rest/namespace/{directoryName}/")
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@Consumes(MediaType.TEXT_XML)
Future<? extends BoundedSortedSet<? extends DirectoryEntry>> listDirectory(
@PathParam("directoryName") String directoryName, ListOptions... options);
/**
* @see AtmosStorageClient#createDirectory
*/
@POST
@Path("/rest/namespace/{directoryName}/")
@ExceptionParser(ReturnEndpointIfAlreadyExists.class)
@Consumes(MediaType.WILDCARD)
Future<URI> createDirectory(@PathParam("directoryName") String directoryName);
/**
* @see AtmosStorageClient#createFile
*/
@POST
@Path("/rest/namespace/{parent}/{name}")
@Consumes(MediaType.WILDCARD)
Future<URI> createFile(
@PathParam("parent") String parent,
@PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindAtmosObjectToEntityAndMetadataToHeaders.class) AtmosObject object);
/**
* @see AtmosStorageClient#updateFile
*/
@PUT
@Path("/rest/namespace/{parent}/{name}")
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Consumes(MediaType.WILDCARD)
Future<Void> updateFile(
@PathParam("parent") String parent,
@PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindAtmosObjectToEntityAndMetadataToHeaders.class) AtmosObject object);
/**
* @see AtmosStorageClient#readFile
*/
@GET
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
Future<AtmosObject> readFile(@PathParam("path") String path, GetOptions... options);
/**
* @see AtmosStorageClient#headFile
*/
@HEAD
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
Future<AtmosObject> headFile(@PathParam("path") String path);
/**
* @see AtmosStorageClient#getSystemMetadata
*/
@HEAD
@ResponseParser(ParseSystemMetadataFromHeaders.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
// currently throws 403 errors @QueryParams(keys = "metadata/system")
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
Future<SystemMetadata> getSystemMetadata(@PathParam("path") String path);
/**
* @see AtmosStorageClient#getUserMetadata
*/
@HEAD
@ResponseParser(ParseSystemMetadataFromHeaders.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("/rest/namespace/{path}")
@QueryParams(keys = "metadata/user")
@Consumes(MediaType.WILDCARD)
Future<UserMetadata> getUserMetadata(@PathParam("path") String path);
/**
* @see AtmosStorageClient#deletePath
*/
@DELETE
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
Future<Void> deletePath(@PathParam("path") String path);
/**
* @see AtmosStorageClient#pathExists
*/
@HEAD
@ExceptionParser(ReturnFalseOn404.class)
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
Future<Boolean> pathExists(@PathParam("path") String path);
// signature currently doesn't work
// @POST
// @QueryParams(keys = "acl")
// @Headers(keys = { "x-emc-useracl", "x-emc-groupacl" }, values = { "root=FULL_CONTROL",
// "other=READ" })
// @Consumes(MediaType.WILDCARD)
// void makePublic(@Endpoint URI url);
}

View File

@ -24,122 +24,48 @@
package org.jclouds.atmosonline.saas;
import java.net.URI;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
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.atmosonline.saas.binders.BindAtmosObjectToEntityAndMetadataToHeaders;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.BoundedSortedSet;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.SystemMetadata;
import org.jclouds.atmosonline.saas.domain.UserMetadata;
import org.jclouds.atmosonline.saas.filters.SignRequest;
import org.jclouds.atmosonline.saas.functions.AtmosObjectName;
import org.jclouds.atmosonline.saas.functions.ParseDirectoryListFromContentAndHeaders;
import org.jclouds.atmosonline.saas.functions.ParseObjectFromHeadersAndHttpContent;
import org.jclouds.atmosonline.saas.functions.ParseSystemMetadataFromHeaders;
import org.jclouds.atmosonline.saas.functions.ReturnEndpointIfAlreadyExists;
import org.jclouds.atmosonline.saas.options.ListOptions;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.concurrent.Timeout;
import org.jclouds.http.options.GetOptions;
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;
/**
* Provides access to EMC Atmos Online Storage resources via their REST API.
* <p/>
*
* @see AtmosStorageAsyncClient
* @see <a href="https://community.emc.com/community/labs/atmos_online" />
* @author Adrian Cole
*/
@Endpoint(AtmosStorage.class)
@RequestFilters(SignRequest.class)
@SkipEncoding( { '/' })
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
public interface AtmosStorageClient {
AtmosObject newObject();
@GET
@Path("/rest/namespace")
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@Consumes(MediaType.TEXT_XML)
Future<? extends BoundedSortedSet<? extends DirectoryEntry>> listDirectories(
BoundedSortedSet<? extends DirectoryEntry> listDirectories(ListOptions... options);
BoundedSortedSet<? extends DirectoryEntry> listDirectory(String directoryName,
ListOptions... options);
@GET
@Path("/rest/namespace/{directoryName}/")
@ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
@Consumes(MediaType.TEXT_XML)
Future<? extends BoundedSortedSet<? extends DirectoryEntry>> listDirectory(
@PathParam("directoryName") String directoryName, ListOptions... options);
URI createDirectory(String directoryName);
@POST
@Path("/rest/namespace/{directoryName}/")
@ExceptionParser(ReturnEndpointIfAlreadyExists.class)
@Consumes(MediaType.WILDCARD)
Future<URI> createDirectory(@PathParam("directoryName") String directoryName);
URI createFile(String parent, AtmosObject object);
@POST
@Path("/rest/namespace/{parent}/{name}")
@Consumes(MediaType.WILDCARD)
Future<URI> createFile(
@PathParam("parent") String parent,
@PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindAtmosObjectToEntityAndMetadataToHeaders.class) AtmosObject object);
void updateFile(String parent, AtmosObject object);
@PUT
@Path("/rest/namespace/{parent}/{name}")
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Consumes(MediaType.WILDCARD)
Future<Void> updateFile(
@PathParam("parent") String parent,
@PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindAtmosObjectToEntityAndMetadataToHeaders.class) AtmosObject object);
AtmosObject readFile(String path, GetOptions... options);
@GET
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
Future<AtmosObject> readFile(@PathParam("path") String path, GetOptions... options);
AtmosObject headFile(String path);
@HEAD
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
AtmosObject headFile(@PathParam("path") String path);
SystemMetadata getSystemMetadata(String path);
@HEAD
@ResponseParser(ParseSystemMetadataFromHeaders.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
// currently throws 403 errors @QueryParams(keys = "metadata/system")
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
SystemMetadata getSystemMetadata(@PathParam("path") String path);
@HEAD
@ResponseParser(ParseSystemMetadataFromHeaders.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("/rest/namespace/{path}")
@QueryParams(keys = "metadata/user")
@Consumes(MediaType.WILDCARD)
UserMetadata getUserMetadata(@PathParam("path") String path);
UserMetadata getUserMetadata(String path);
/**
*
@ -148,17 +74,9 @@ public interface AtmosStorageClient {
* @throws AtmosStorageResponseException
* , if the path is a directory and not empty
*/
@DELETE
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
Future<Void> deletePath(@PathParam("path") String path);
void deletePath(String path);
@HEAD
@ExceptionParser(ReturnFalseOn404.class)
@Path("/rest/namespace/{path}")
@Consumes(MediaType.WILDCARD)
boolean pathExists(@PathParam("path") String path);
boolean pathExists(String path);
// signature currently doesn't work
// @POST

View File

@ -38,10 +38,12 @@ import com.google.inject.TypeLiteral;
*
* @author Adrian Cole
*/
public class AtmosStorageContextBuilder extends RestContextBuilder<AtmosStorageClient> {
public class AtmosStorageContextBuilder extends
RestContextBuilder<AtmosStorageAsyncClient, AtmosStorageClient> {
public AtmosStorageContextBuilder(Properties props) {
super(new TypeLiteral<AtmosStorageClient>() {
super(new TypeLiteral<AtmosStorageAsyncClient>() {
}, new TypeLiteral<AtmosStorageClient>() {
}, props);
}

View File

@ -0,0 +1,199 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.atmosonline.saas.blobstore;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import java.net.URI;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.inject.Inject;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.blobstore.functions.BlobStoreListOptionsToListOptions;
import org.jclouds.atmosonline.saas.blobstore.functions.BlobToObject;
import org.jclouds.atmosonline.saas.blobstore.functions.DirectoryEntryListToResourceMetadataList;
import org.jclouds.atmosonline.saas.blobstore.functions.ObjectToBlob;
import org.jclouds.atmosonline.saas.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.atmosonline.saas.blobstore.internal.BaseAtmosBlobStore;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.options.ListOptions;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.concurrent.FutureFunctionCallable;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.util.Utils;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
public class AtmosAsyncBlobStore extends BaseAtmosBlobStore implements AsyncBlobStore {
@Inject
public AtmosAsyncBlobStore(AtmosStorageAsyncClient async, AtmosStorageClient sync,
Factory blobFactory, LoggerFactory logFactory,
ClearListStrategy clearContainerStrategy, ObjectToBlobMetadata object2BlobMd,
ObjectToBlob object2Blob, BlobToObject blob2Object,
BlobStoreListOptionsToListOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions,
DirectoryEntryListToResourceMetadataList container2ResourceList, ExecutorService service) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions,
container2ResourceList, service);
}
/**
* This implementation uses the AtmosStorage HEAD Object command to return the result
*/
public Future<BlobMetadata> blobMetadata(String container, String key) {
return wrapFuture(async.headFile(container + "/" + key),
new Function<AtmosObject, BlobMetadata>() {
@Override
public BlobMetadata apply(AtmosObject from) {
return object2BlobMd.apply(from);
}
});
}
public Future<Void> clearContainer(final String container) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
return null;
}
});
}
public Future<Boolean> createContainer(String container) {
return wrapFuture(async.createDirectory(container), new Function<URI, Boolean>() {
public Boolean apply(URI from) {
return true;// no etag
}
});
}
public Future<Void> deleteContainer(final String container) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
async.deletePath(container).get();
if (!Utils.enventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
return !sync.pathExists(container);
}
}, requestTimeoutMilliseconds)) {
throw new IllegalStateException(container + " still exists after deleting!");
}
return null;
}
});
}
public Future<Boolean> exists(String container) {
return async.pathExists(container);
}
public Future<Blob> getBlob(String container, String key,
org.jclouds.blobstore.options.GetOptions... optionsList) {
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
Future<AtmosObject> returnVal = async.readFile(container + "/" + key, httpOptions);
return wrapFuture(returnVal, object2Blob);
}
public Future<? extends ListResponse<? extends ResourceMetadata>> list() {
return wrapFuture(async.listDirectories(), container2ResourceList);
}
public Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(
String container, org.jclouds.blobstore.options.ListContainerOptions... optionsList) {
if (optionsList.length == 1) {
if (optionsList[0].isRecursive()) {
throw new UnsupportedOperationException("recursive not currently supported in emcsaas");
}
if (optionsList[0].getPath() != null) {
container = container + "/" + optionsList[0].getPath();
}
}
ListOptions nativeOptions = container2ContainerListOptions.apply(optionsList);
return wrapFuture(async.listDirectory(container, nativeOptions), container2ResourceList);
}
/**
* Since there is no etag support in atmos, we just return the path.
*/
public Future<String> putBlob(final String container, final Blob blob) {
final String path = container + "/" + blob.getMetadata().getName();
Callable<String> valueCallable = new FutureFunctionCallable<Void, String>(async
.deletePath(path), new Function<Void, String>() {
public String apply(Void from) {
try {
if (!Utils.enventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
return !sync.pathExists(path);
}
}, requestTimeoutMilliseconds)) {
throw new IllegalStateException(path + " still exists after deleting!");
}
if (blob.getMetadata().getContentMD5() != null)
blob.getMetadata().getUserMetadata().put("content-md5",
HttpUtils.toHexString(blob.getMetadata().getContentMD5()));
sync.createFile(container, blob2Object.apply(blob));
return path;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
return service.submit(valueCallable);
}
public Future<Void> removeBlob(String container, String key) {
return async.deletePath(container + "/" + key);
}
}

View File

@ -23,155 +23,105 @@
*/
package org.jclouds.atmosonline.saas.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import java.net.URI;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.blobstore.functions.BlobStoreListOptionsToListOptions;
import org.jclouds.atmosonline.saas.blobstore.functions.BlobToObject;
import org.jclouds.atmosonline.saas.blobstore.functions.DirectoryEntryListToResourceMetadataList;
import org.jclouds.atmosonline.saas.blobstore.functions.ObjectToBlob;
import org.jclouds.atmosonline.saas.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.blobstore.internal.BaseAtmosBlobStore;
import org.jclouds.atmosonline.saas.options.ListOptions;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.attr.ConsistencyModels;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.concurrent.FutureFunctionCallable;
import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.http.HttpUtils;
import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.util.Utils;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
@ConsistencyModel(ConsistencyModels.EVENTUAL)
public class AtmosBlobStore implements BlobStore {
private final AtmosStorageClient connection;
private final Blob.Factory blobFactory;
private final LoggerFactory logFactory;
private final ClearListStrategy clearContainerStrategy;
private final ObjectToBlobMetadata object2BlobMd;
private final ObjectToBlob object2Blob;
private final BlobToObject blob2Object;
private final BlobStoreListOptionsToListOptions container2ContainerListOptions;
private final BlobToHttpGetOptions blob2ObjectGetOptions;
private final DirectoryEntryListToResourceMetadataList container2ResourceList;
private final ExecutorService service;
@Inject(optional = true)
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
protected long requestTimeoutMilliseconds = 30000;
public class AtmosBlobStore extends BaseAtmosBlobStore implements BlobStore {
@Inject
private AtmosBlobStore(AtmosStorageClient connection, Blob.Factory blobFactory,
LoggerFactory logFactory, ClearListStrategy clearContainerStrategy,
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object,
public AtmosBlobStore(AtmosStorageAsyncClient async, AtmosStorageClient sync,
Factory blobFactory, LoggerFactory logFactory,
ClearListStrategy clearContainerStrategy, ObjectToBlobMetadata object2BlobMd,
ObjectToBlob object2Blob, BlobToObject blob2Object,
BlobStoreListOptionsToListOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions,
DirectoryEntryListToResourceMetadataList container2ResourceList, ExecutorService service) {
this.connection = checkNotNull(connection, "connection");
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
this.logFactory = checkNotNull(logFactory, "logFactory");
this.clearContainerStrategy = checkNotNull(clearContainerStrategy, "clearContainerStrategy");
this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd");
this.object2Blob = checkNotNull(object2Blob, "object2Blob");
this.blob2Object = checkNotNull(blob2Object, "blob2Object");
this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions,
"container2ContainerListOptions");
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
this.container2ResourceList = checkNotNull(container2ResourceList, "container2ResourceList");
this.service = checkNotNull(service, "service");
}
protected <F, T> Future<T> wrapFuture(Future<? extends F> future, Function<F, T> function) {
return new FutureFunctionWrapper<F, T>(future, function, logFactory.getLogger(function
.getClass().getName()));
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions,
container2ResourceList, service);
}
/**
* This implementation uses the AtmosStorage HEAD Object command to return the result
*/
public BlobMetadata blobMetadata(String container, String key) {
return object2BlobMd.apply(connection.headFile(container + "/" + key));
return object2BlobMd.apply(sync.headFile(container + "/" + key));
}
public Future<Void> clearContainer(final String container) {
return service.submit(new Callable<Void>() {
public void clearContainer(final String container) {
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
return null;
}
});
clearContainerStrategy.execute(container, recursive());
}
public Future<Boolean> createContainer(String container) {
return wrapFuture(connection.createDirectory(container), new Function<URI, Boolean>() {
public Boolean apply(URI from) {
return true;// no etag
}
});
public boolean createContainer(String container) {
sync.createDirectory(container);
return true;// no etag
}
public Future<Void> deleteContainer(final String container) {
return service.submit(new Callable<Void>() {
public void deleteContainer(final String container) {
clearContainerStrategy.execute(container, recursive());
deleteAndEnsurePathGone(container);
}
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
connection.deletePath(container).get();
if (!Utils.enventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
return !connection.pathExists(container);
}
}, requestTimeoutMilliseconds)) {
throw new IllegalStateException(container + " still exists after deleting!");
private void deleteAndEnsurePathGone(final String path) {
sync.deletePath(path);
try {
if (!Utils.enventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
return !sync.pathExists(path);
}
return null;
}, 30000)) {
throw new IllegalStateException(path + " still exists after deleting!");
}
});
} catch (InterruptedException e) {
new IllegalStateException(path + " interrupted during deletion!", e);
}
}
public boolean exists(String container) {
return connection.pathExists(container);
return sync.pathExists(container);
}
public Future<Blob> getBlob(String container, String key,
public Blob getBlob(String container, String key,
org.jclouds.blobstore.options.GetOptions... optionsList) {
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
Future<AtmosObject> returnVal = connection.readFile(container + "/" + key, httpOptions);
return wrapFuture(returnVal, object2Blob);
return object2Blob.apply(sync.readFile(container + "/" + key, httpOptions));
}
public Future<? extends ListResponse<? extends ResourceMetadata>> list() {
return wrapFuture(connection.listDirectories(), container2ResourceList);
public ListResponse<? extends ResourceMetadata> list() {
return container2ResourceList.apply(sync.listDirectories());
}
public Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(
String container, org.jclouds.blobstore.options.ListContainerOptions... optionsList) {
public ListContainerResponse<? extends ResourceMetadata> list(String container,
org.jclouds.blobstore.options.ListContainerOptions... optionsList) {
if (optionsList.length == 1) {
if (optionsList[0].isRecursive()) {
throw new UnsupportedOperationException("recursive not currently supported in emcsaas");
@ -181,50 +131,24 @@ public class AtmosBlobStore implements BlobStore {
}
}
ListOptions nativeOptions = container2ContainerListOptions.apply(optionsList);
return wrapFuture(connection.listDirectory(container, nativeOptions), container2ResourceList);
return container2ResourceList.apply(sync.listDirectory(container, nativeOptions));
}
/**
* Since there is no etag support in atmos, we just return the path.
*/
public Future<String> putBlob(final String container, final Blob blob) {
public String putBlob(final String container, final Blob blob) {
final String path = container + "/" + blob.getMetadata().getName();
Callable<String> valueCallable = new FutureFunctionCallable<Void, String>(connection
.deletePath(path), new Function<Void, String>() {
public String apply(Void from) {
try {
if (!Utils.enventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
return !connection.pathExists(path);
}
}, requestTimeoutMilliseconds)) {
throw new IllegalStateException(path + " still exists after deleting!");
}
if (blob.getMetadata().getContentMD5() != null)
blob.getMetadata().getUserMetadata().put("content-md5",
HttpUtils.toHexString(blob.getMetadata().getContentMD5()));
connection.createFile(container, blob2Object.apply(blob)).get();
return path;
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
});
return service.submit(valueCallable);
deleteAndEnsurePathGone(path);
if (blob.getMetadata().getContentMD5() != null)
blob.getMetadata().getUserMetadata().put("content-md5",
HttpUtils.toHexString(blob.getMetadata().getContentMD5()));
sync.createFile(container, blob2Object.apply(blob));
return path;
}
public Future<Void> removeBlob(String container, String key) {
return connection.deletePath(container + "/" + key);
}
public Blob newBlob() {
return blobFactory.create(null);
public void removeBlob(String container, String key) {
sync.deletePath(container + "/" + key);
}
}

View File

@ -33,6 +33,7 @@ import java.util.Properties;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.blobstore.config.AtmosBlobStoreContextModule;
import org.jclouds.atmosonline.saas.config.AtmosStorageRestClientModule;
@ -58,10 +59,12 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole, Andrew Newdigate
* @see AtmosBlobStoreContext
*/
public class AtmosBlobStoreContextBuilder extends BlobStoreContextBuilder<AtmosStorageClient> {
public class AtmosBlobStoreContextBuilder extends
BlobStoreContextBuilder<AtmosStorageAsyncClient, AtmosStorageClient> {
public AtmosBlobStoreContextBuilder(Properties props) {
super(new TypeLiteral<AtmosStorageClient>() {
super(new TypeLiteral<AtmosStorageAsyncClient>() {
}, new TypeLiteral<AtmosStorageClient>() {
}, convert(props));
}

View File

@ -26,6 +26,7 @@ package org.jclouds.atmosonline.saas.blobstore;
import java.net.URI;
import java.util.Properties;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.AtmosStoragePropertiesBuilder;
import org.jclouds.blobstore.BlobStoreContext;
@ -47,20 +48,20 @@ import com.google.inject.Module;
* @see AtmosBlobStoreContext
*/
public class AtmosBlobStoreContextFactory {
public static BlobStoreContext<AtmosStorageClient> createContext(Properties properties,
Module... modules) {
public static BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient> createContext(
Properties properties, Module... modules) {
return new AtmosBlobStoreContextBuilder(new AtmosStoragePropertiesBuilder(properties).build())
.withModules(modules).buildContext();
}
public static BlobStoreContext<AtmosStorageClient> createContext(String uid, String key,
Module... modules) {
public static BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient> createContext(
String uid, String key, Module... modules) {
return new AtmosBlobStoreContextBuilder(new AtmosStoragePropertiesBuilder(uid, key).build())
.withModules(modules).buildContext();
}
public static BlobStoreContext<AtmosStorageClient> createContext(URI endpoint, String uid,
String key, Module... modules) {
public static BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient> createContext(
URI endpoint, String uid, String key, Module... modules) {
return new AtmosBlobStoreContextBuilder(new AtmosStoragePropertiesBuilder(uid, key)
.withEndpoint(endpoint).build()).withModules(modules).buildContext();
}

View File

@ -29,12 +29,15 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.AtmosStorage;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.blobstore.AtmosAsyncBlobStore;
import org.jclouds.atmosonline.saas.blobstore.AtmosBlobStore;
import org.jclouds.atmosonline.saas.blobstore.strategy.FindMD5InUserMetadata;
import org.jclouds.atmosonline.saas.blobstore.strategy.RecursiveRemove;
import org.jclouds.atmosonline.saas.config.AtmosObjectModule;
import org.jclouds.atmosonline.saas.reference.AtmosStorageConstants;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobMap;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
@ -51,7 +54,7 @@ import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* Configures the {@link AtmosBlobStoreContext}; requires {@link AtmosBlobStore} bound.
* Configures the {@link AtmosBlobStoreContext}; requires {@link AtmosAsyncBlobStore} bound.
*
* @author Adrian Cole
*/
@ -62,6 +65,7 @@ public class AtmosBlobStoreContextModule extends AbstractModule {
install(new BlobStoreObjectModule());
install(new BlobStoreMapModule());
install(new AtmosObjectModule());
bind(AsyncBlobStore.class).to(AtmosAsyncBlobStore.class).asEagerSingleton();
bind(BlobStore.class).to(AtmosBlobStore.class).asEagerSingleton();
bind(ContainsValueInListStrategy.class).to(FindMD5InUserMetadata.class);
bind(ClearListStrategy.class).to(RecursiveRemove.class);
@ -70,12 +74,13 @@ public class AtmosBlobStoreContextModule extends AbstractModule {
@Provides
@Singleton
BlobStoreContext<AtmosStorageClient> provideContext(BlobMap.Factory blobMapFactory,
InputStreamMap.Factory inputStreamMapFactory, Closer closer, BlobStore blobStore,
BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient> provideContext(
BlobMap.Factory blobMapFactory, InputStreamMap.Factory inputStreamMapFactory,
Closer closer, AsyncBlobStore asynchBlobStore, BlobStore blobStore, AtmosStorageAsyncClient async,
AtmosStorageClient defaultApi, @AtmosStorage URI endPoint,
@Named(AtmosStorageConstants.PROPERTY_EMCSAAS_UID) String account) {
return new BlobStoreContextImpl<AtmosStorageClient>(blobMapFactory, inputStreamMapFactory,
closer, blobStore, defaultApi, endPoint, account);
return new BlobStoreContextImpl<AtmosStorageAsyncClient, AtmosStorageClient>(blobMapFactory,
inputStreamMapFactory, closer, asynchBlobStore, blobStore, async, defaultApi, endPoint, account);
}
}

View File

@ -0,0 +1,100 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.atmosonline.saas.blobstore.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.blobstore.functions.BlobStoreListOptionsToListOptions;
import org.jclouds.atmosonline.saas.blobstore.functions.BlobToObject;
import org.jclouds.atmosonline.saas.blobstore.functions.DirectoryEntryListToResourceMetadataList;
import org.jclouds.atmosonline.saas.blobstore.functions.ObjectToBlob;
import org.jclouds.atmosonline.saas.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.reference.BlobStoreConstants;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.logging.Logger.LoggerFactory;
import com.google.common.base.Function;
public class BaseAtmosBlobStore {
protected final AtmosStorageAsyncClient async;
protected final AtmosStorageClient sync;
protected final Blob.Factory blobFactory;
protected final LoggerFactory logFactory;
protected final ClearListStrategy clearContainerStrategy;
protected final ObjectToBlobMetadata object2BlobMd;
protected final ObjectToBlob object2Blob;
protected final BlobToObject blob2Object;
protected final BlobStoreListOptionsToListOptions container2ContainerListOptions;
protected final BlobToHttpGetOptions blob2ObjectGetOptions;
protected final DirectoryEntryListToResourceMetadataList container2ResourceList;
protected final ExecutorService service;
@Inject(optional = true)
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
protected long requestTimeoutMilliseconds = 30000;
@Inject
protected BaseAtmosBlobStore(AtmosStorageAsyncClient async, AtmosStorageClient sync,
Blob.Factory blobFactory, LoggerFactory logFactory,
ClearListStrategy clearContainerStrategy, ObjectToBlobMetadata object2BlobMd,
ObjectToBlob object2Blob, BlobToObject blob2Object,
BlobStoreListOptionsToListOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions,
DirectoryEntryListToResourceMetadataList container2ResourceList, ExecutorService service) {
this.async = checkNotNull(async, "async");
this.sync = checkNotNull(sync, "sync");
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
this.logFactory = checkNotNull(logFactory, "logFactory");
this.clearContainerStrategy = checkNotNull(clearContainerStrategy, "clearContainerStrategy");
this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd");
this.object2Blob = checkNotNull(object2Blob, "object2Blob");
this.blob2Object = checkNotNull(blob2Object, "blob2Object");
this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions,
"container2ContainerListOptions");
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
this.container2ResourceList = checkNotNull(container2ResourceList, "container2ResourceList");
this.service = checkNotNull(service, "service");
}
protected <F, T> Future<T> wrapFuture(Future<? extends F> future, Function<F, T> function) {
return new FutureFunctionWrapper<F, T>(future, function, logFactory.getLogger(function
.getClass().getName()));
}
public Blob newBlob() {
return blobFactory.create(null);
}
}

View File

@ -34,6 +34,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.domain.DirectoryEntry;
import org.jclouds.atmosonline.saas.domain.FileType;
@ -63,14 +64,16 @@ public class RecursiveRemove implements ClearListStrategy, ClearContainerStrateg
@Inject(optional = true)
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
protected long requestTimeoutMilliseconds = 30000;
protected final AtmosStorageClient connection;
protected final AtmosStorageAsyncClient async;
protected final AtmosStorageClient sync;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public RecursiveRemove(AtmosStorageClient connection) {
this.connection = connection;
public RecursiveRemove(AtmosStorageAsyncClient connection, AtmosStorageClient sync) {
this.async = connection;
this.sync = sync;
}
public void execute(String containerName) {
@ -83,28 +86,30 @@ public class RecursiveRemove implements ClearListStrategy, ClearContainerStrateg
throws InterruptedException, ExecutionException, TimeoutException {
Set<Future<Void>> deletes = Sets.newHashSet();
if ((type == FileType.DIRECTORY) && recursive) {
for (DirectoryEntry child : connection.listDirectory(fullPath).get(10, TimeUnit.SECONDS)) {
for (DirectoryEntry child : async.listDirectory(fullPath).get(10, TimeUnit.SECONDS)) {
deletes.add(rm(fullPath + "/" + child.getObjectName(), child.getType(), true));
}
}
for (Future<Void> isdeleted : deletes) {
isdeleted.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
}
return new FutureFunctionWrapper<Void, Void>(connection.deletePath(fullPath),
return new FutureFunctionWrapper<Void, Void>(async.deletePath(fullPath),
new Function<Void, Void>() {
public Void apply(Void from) {
try {
if (!Utils.enventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
return !connection.pathExists(fullPath);
return !sync.pathExists(fullPath);
}
}, requestTimeoutMilliseconds)) {
throw new IllegalStateException(fullPath + " still exists after deleting!");
throw new IllegalStateException(fullPath
+ " still exists after deleting!");
}
return null;
} catch (InterruptedException e) {
throw new IllegalStateException(fullPath + " still exists after deleting!",e);
throw new IllegalStateException(fullPath + " still exists after deleting!",
e);
}
}
@ -117,7 +122,7 @@ public class RecursiveRemove implements ClearListStrategy, ClearContainerStrateg
path += "/" + options.getPath();
Set<Future<Void>> deletes = Sets.newHashSet();
try {
for (DirectoryEntry md : connection.listDirectory(path).get(requestTimeoutMilliseconds,
for (DirectoryEntry md : async.listDirectory(path).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS)) {
deletes.add(rm(path + "/" + md.getObjectName(), md.getType(), options.isRecursive()));
}

View File

@ -29,6 +29,7 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.AtmosStorage;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.reference.AtmosStorageConstants;
import org.jclouds.blobstore.config.BlobStoreObjectModule;
@ -52,10 +53,12 @@ public class AtmosStorageContextModule extends AbstractModule {
@Provides
@Singleton
RestContext<AtmosStorageClient> provideContext(Closer closer, AtmosStorageClient defaultApi,
RestContext<AtmosStorageAsyncClient, AtmosStorageClient> provideContext(Closer closer,
AtmosStorageAsyncClient async, AtmosStorageClient defaultApi,
@AtmosStorage URI endPoint,
@Named(AtmosStorageConstants.PROPERTY_EMCSAAS_UID) String account) {
return new RestContextImpl<AtmosStorageClient>(closer, defaultApi, endPoint, account);
return new RestContextImpl<AtmosStorageAsyncClient, AtmosStorageClient>(closer, async,
defaultApi, endPoint, account);
}
}

View File

@ -33,10 +33,12 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.AtmosStorage;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.handlers.AtmosStorageClientErrorRetryHandler;
import org.jclouds.atmosonline.saas.handlers.ParseAtmosStorageErrorFromXmlContent;
import org.jclouds.concurrent.ExpirableSupplier;
import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
@ -75,8 +77,16 @@ public class AtmosStorageRestClientModule extends AbstractModule {
}
@Provides
protected AtmosStorageClient provideClient(RestClientFactory factory) {
return factory.create(AtmosStorageClient.class);
@Singleton
protected AtmosStorageAsyncClient provideAsyncClient(RestClientFactory factory) {
return factory.create(AtmosStorageAsyncClient.class);
}
@Provides
@Singleton
public AtmosStorageClient provideClient(AtmosStorageAsyncClient client)
throws IllegalArgumentException, SecurityException, NoSuchMethodException {
return SyncProxy.create(AtmosStorageClient.class, client);
}
@Provides

View File

@ -32,7 +32,6 @@ import java.lang.reflect.UndeclaredThrowableException;
import java.net.URI;
import java.security.SecureRandom;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.commons.io.IOUtils;
@ -49,6 +48,7 @@ import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.blobstore.strategy.ClearContainerStrategy;
import org.jclouds.http.HttpResponseException;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.util.Utils;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@ -118,20 +118,22 @@ public class AtmosStorageClientLiveTest {
String uid = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
connection = new AtmosStorageContextBuilder(new AtmosStoragePropertiesBuilder(uid, key)
.build()).withModules(new Log4JLoggingModule()).buildContext().getApi();
ClearContainerStrategy clearer = new RecursiveRemove(connection);
for (DirectoryEntry entry : connection.listDirectories().get(10, TimeUnit.SECONDS)) {
RestContext<AtmosStorageAsyncClient, AtmosStorageClient> context = new AtmosStorageContextBuilder(
new AtmosStoragePropertiesBuilder(uid, key).build()).withModules(
new Log4JLoggingModule()).buildContext();
connection = context.getApi();
ClearContainerStrategy clearer = new RecursiveRemove(context.getAsyncApi(), connection);
for (DirectoryEntry entry : connection.listDirectories()) {
if (entry.getObjectName().startsWith(containerPrefix)) {
clearer.execute(entry.getObjectName());
deleteConfirmed(entry.getObjectName());
}
}
}
@Test
public void testListDirectorys() throws Exception {
BoundedSortedSet<? extends DirectoryEntry> response = connection.listDirectories().get(10,
TimeUnit.SECONDS);
BoundedSortedSet<? extends DirectoryEntry> response = connection.listDirectories();
assert null != response;
}
@ -145,7 +147,7 @@ public class AtmosStorageClientLiveTest {
while (!created) {
privateDirectory = containerPrefix + new SecureRandom().nextInt();
try {
created = connection.createDirectory(privateDirectory).get(10, TimeUnit.SECONDS) != null;
created = connection.createDirectory(privateDirectory) != null;
} catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
if (htpe.getResponse().getStatusCode() == 409)
@ -153,11 +155,10 @@ public class AtmosStorageClientLiveTest {
throw e;
}
}
BoundedSortedSet<? extends DirectoryEntry> response = connection.listDirectories().get(10,
TimeUnit.SECONDS);
BoundedSortedSet<? extends DirectoryEntry> response = connection.listDirectories();
for (DirectoryEntry id : response) {
BoundedSortedSet<? extends DirectoryEntry> r2 = connection.listDirectory(id.getObjectName()).get(10,
TimeUnit.SECONDS);
BoundedSortedSet<? extends DirectoryEntry> r2 = connection.listDirectory(id
.getObjectName());
assert r2 != null;
}
}
@ -168,7 +169,7 @@ public class AtmosStorageClientLiveTest {
createOrReplaceObject("object3", "here is my data!", "meta-value1");
createOrReplaceObject("object4", "here is my data!", "meta-value1");
BoundedSortedSet<? extends DirectoryEntry> r2 = connection.listDirectory(privateDirectory,
ListOptions.Builder.limit(1)).get(10, TimeUnit.SECONDS);
ListOptions.Builder.limit(1));
// test bug exists:
assertEquals(r2.size(), 3);
// assertEquals(r2.size(), 1);
@ -279,7 +280,7 @@ public class AtmosStorageClientLiveTest {
private static void verifyObject(AtmosStorageClient connection, String path, String compare,
String metadataValue) throws InterruptedException, ExecutionException,
TimeoutException, IOException {
AtmosObject getBlob = connection.readFile(path).get(120, TimeUnit.SECONDS);
AtmosObject getBlob = connection.readFile(path);
assertEquals(getBlob.getData() instanceof String ? getBlob.getData() : IOUtils
.toString((InputStream) getBlob.getData()), compare);
verifyMetadata(metadataValue, getBlob);
@ -323,7 +324,7 @@ public class AtmosStorageClientLiveTest {
deleteConfirmed(privateDirectory + "/" + object.getContentMetadata().getName());
long time = System.currentTimeMillis();
try {
connection.createFile(privateDirectory, object).get(30, TimeUnit.SECONDS);
connection.createFile(privateDirectory, object);
System.err.printf("%s %s; %dms%n", "created",
object.getData() instanceof InputStream ? "stream" : "string", System
.currentTimeMillis()
@ -349,7 +350,7 @@ public class AtmosStorageClientLiveTest {
private void deleteImmediateAndVerifyWithHead(final String path) throws InterruptedException,
ExecutionException, TimeoutException {
try {
connection.deletePath(path).get(10, TimeUnit.SECONDS);
connection.deletePath(path);
} catch (KeyNotFoundException ex) {
}
assert !connection.pathExists(path);
@ -358,7 +359,7 @@ public class AtmosStorageClientLiveTest {
protected void deleteConsistencyAware(final String path) throws InterruptedException,
ExecutionException, TimeoutException {
try {
connection.deletePath(path).get(10, TimeUnit.SECONDS);
connection.deletePath(path);
} catch (KeyNotFoundException ex) {
}
assert Utils.enventuallyTrue(new Supplier<Boolean>() {
@ -399,9 +400,9 @@ public class AtmosStorageClientLiveTest {
}
try {
if (update)
connection.updateFile(privateDirectory, object).get(30, TimeUnit.SECONDS);
connection.updateFile(privateDirectory, object);
else
connection.createFile(privateDirectory, object).get(30, TimeUnit.SECONDS);
connection.createFile(privateDirectory, object);
System.err.printf("%s %s; %dms%n", update ? "updated" : "created",
object.getData() instanceof InputStream ? "stream" : "string", System
.currentTimeMillis()

View File

@ -70,14 +70,14 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "emcsaas.AtmosStorageClientTest")
public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
public class AtmosStorageClientTest extends RestClientTest<AtmosStorageAsyncClient> {
private BlobToObject blobToObject;
public void testListDirectories() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageClient.class.getMethod("listDirectories", Array.newInstance(
Method method = AtmosStorageAsyncClient.class.getMethod("listDirectories", Array.newInstance(
ListOptions.class, 0).getClass());
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method);
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method);
assertRequestLineEquals(httpMethod,
"GET http://accesspoint.emccis.com/rest/namespace HTTP/1.1");
@ -93,9 +93,9 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
}
public void testListDirectory() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageClient.class.getMethod("listDirectory", String.class, Array
Method method = AtmosStorageAsyncClient.class.getMethod("listDirectory", String.class, Array
.newInstance(ListOptions.class, 0).getClass());
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method,
"directory");
assertRequestLineEquals(httpMethod,
@ -113,9 +113,9 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
public void testListDirectoriesOptions() throws SecurityException, NoSuchMethodException,
IOException {
Method method = AtmosStorageClient.class.getMethod("listDirectories", Array.newInstance(
Method method = AtmosStorageAsyncClient.class.getMethod("listDirectories", Array.newInstance(
ListOptions.class, 0).getClass());
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method,
new ListOptions().limit(1).token("asda"));
assertRequestLineEquals(httpMethod,
@ -134,9 +134,9 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
public void testListDirectoryOptions() throws SecurityException, NoSuchMethodException,
IOException {
Method method = AtmosStorageClient.class.getMethod("listDirectory", String.class, Array
Method method = AtmosStorageAsyncClient.class.getMethod("listDirectory", String.class, Array
.newInstance(ListOptions.class, 0).getClass());
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method,
"directory", new ListOptions().limit(1).token("asda"));
assertRequestLineEquals(httpMethod,
@ -154,8 +154,9 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
}
public void testCreateDirectory() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageClient.class.getMethod("createDirectory", String.class);
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method, "dir");
Method method = AtmosStorageAsyncClient.class.getMethod("createDirectory", String.class);
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method,
"dir");
assertRequestLineEquals(httpMethod,
"POST http://accesspoint.emccis.com/rest/namespace/dir/ HTTP/1.1");
@ -171,10 +172,10 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
}
public void testCreateFile() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageClient.class.getMethod("createFile", String.class,
Method method = AtmosStorageAsyncClient.class.getMethod("createFile", String.class,
AtmosObject.class);
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method, "dir",
blobToObject.apply(BindBlobToMultipartFormTest.TEST_BLOB));
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method,
"dir", blobToObject.apply(BindBlobToMultipartFormTest.TEST_BLOB));
assertRequestLineEquals(httpMethod,
"POST http://accesspoint.emccis.com/rest/namespace/dir/hello HTTP/1.1");
@ -191,10 +192,10 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
}
public void testUpdateFile() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageClient.class.getMethod("updateFile", String.class,
Method method = AtmosStorageAsyncClient.class.getMethod("updateFile", String.class,
AtmosObject.class);
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method, "dir",
blobToObject.apply(BindBlobToMultipartFormTest.TEST_BLOB));
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method,
"dir", blobToObject.apply(BindBlobToMultipartFormTest.TEST_BLOB));
assertRequestLineEquals(httpMethod,
"PUT http://accesspoint.emccis.com/rest/namespace/dir/hello HTTP/1.1");
@ -210,9 +211,9 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
}
public void testReadFile() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageClient.class.getMethod("readFile", String.class, Array
Method method = AtmosStorageAsyncClient.class.getMethod("readFile", String.class, Array
.newInstance(GetOptions.class, 0).getClass());
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method,
"dir/file");
assertRequestLineEquals(httpMethod,
@ -229,8 +230,8 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
}
public void testGetSystemMetadata() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageClient.class.getMethod("getSystemMetadata", String.class);
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method,
Method method = AtmosStorageAsyncClient.class.getMethod("getSystemMetadata", String.class);
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method,
"dir/file");
assertRequestLineEquals(httpMethod,
@ -246,8 +247,8 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
}
public void testDeletePath() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageClient.class.getMethod("deletePath", String.class);
GeneratedHttpRequest<AtmosStorageClient> httpMethod = processor.createRequest(method,
Method method = AtmosStorageAsyncClient.class.getMethod("deletePath", String.class);
GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod = processor.createRequest(method,
"dir/file");
assertRequestLineEquals(httpMethod,
@ -263,19 +264,19 @@ public class AtmosStorageClientTest extends RestClientTest<AtmosStorageClient> {
}
public void testNewObject() throws SecurityException, NoSuchMethodException, IOException {
Method method = AtmosStorageClient.class.getMethod("newObject");
Method method = AtmosStorageAsyncClient.class.getMethod("newObject");
assertEquals(method.getReturnType(), AtmosObject.class);
}
@Override
protected void checkFilters(GeneratedHttpRequest<AtmosStorageClient> httpMethod) {
protected void checkFilters(GeneratedHttpRequest<AtmosStorageAsyncClient> httpMethod) {
assertEquals(httpMethod.getFilters().size(), 1);
assertEquals(httpMethod.getFilters().get(0).getClass(), SignRequest.class);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<AtmosStorageClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<AtmosStorageClient>>() {
protected TypeLiteral<RestAnnotationProcessor<AtmosStorageAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<AtmosStorageAsyncClient>>() {
};
}

View File

@ -30,6 +30,7 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.AtmosStoragePropertiesBuilder;
import org.jclouds.atmosonline.saas.blobstore.config.AtmosBlobStoreContextModule;
@ -37,7 +38,7 @@ import org.jclouds.atmosonline.saas.config.AtmosStorageRestClientModule;
import org.jclouds.atmosonline.saas.config.AtmosStorageStubClientModule;
import org.jclouds.atmosonline.saas.domain.AtmosObject;
import org.jclouds.atmosonline.saas.domain.internal.AtmosObjectImpl;
import org.jclouds.atmosonline.saas.internal.StubAtmosStorageClient;
import org.jclouds.atmosonline.saas.internal.StubAtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.reference.AtmosStorageConstants;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob;
@ -73,20 +74,23 @@ public class AtmosBlobStoreContextBuilderTest {
}
public void testBuildContext() {
BlobStoreContext<AtmosStorageClient> context = newBuilder().buildContext();
BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient> context = newBuilder()
.buildContext();
assertEquals(context.getClass(), BlobStoreContextImpl.class);
assertEquals(context.getApi().getClass(), StubAtmosStorageClient.class);
assertEquals(context.getBlobStore().getClass(), AtmosBlobStore.class);
assertEquals(context.getApi().newObject().getClass(), AtmosObjectImpl.class);
assertEquals(context.getBlobStore().newBlob().getClass(), BlobImpl.class);
assertEquals(context.getAsyncApi().getClass(), StubAtmosStorageAsyncClient.class);
assertEquals(context.getAsyncBlobStore().getClass(), AtmosAsyncBlobStore.class);
assertEquals(context.getAsyncApi().newObject().getClass(), AtmosObjectImpl.class);
assertEquals(context.getAsyncBlobStore().newBlob().getClass(), BlobImpl.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("https://localhost/azurestub"));
}
public void testBuildInjector() {
Injector i = newBuilder().buildInjector();
assert i.getInstance(Key.get(new TypeLiteral<BlobStoreContext<AtmosStorageClient>>() {
})) != null;
assert i
.getInstance(Key
.get(new TypeLiteral<BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient>>() {
})) != null;
assert i.getInstance(AtmosObject.class) != null;
assert i.getInstance(Blob.class) != null;
}

View File

@ -25,6 +25,7 @@ package org.jclouds.atmosonline.saas.blobstore.config;
import static org.testng.Assert.assertEquals;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.blobstore.strategy.FindMD5InUserMetadata;
import org.jclouds.atmosonline.saas.config.AtmosStorageStubClientModule;
@ -71,9 +72,10 @@ public class AtmosBlobStoreModuleTest {
void testContextImpl() {
Injector injector = createInjector();
BlobStoreContext<AtmosStorageClient> handler = injector.getInstance(Key
.get(new TypeLiteral<BlobStoreContext<AtmosStorageClient>>() {
}));
BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient> handler = injector
.getInstance(Key
.get(new TypeLiteral<BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient>>() {
}));
assertEquals(handler.getClass(), BlobStoreContextImpl.class);
ContainsValueInListStrategy valueList = injector
.getInstance(ContainsValueInListStrategy.class);

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.atmosonline.saas.blobstore.integration;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
import org.testng.annotations.Test;
@ -32,12 +33,12 @@ import org.testng.annotations.Test;
*/
@Test(groups = { "integration", "live" }, testName = "emcsaas.AtmosStorageContainerIntegrationTest")
public class AtmosStorageContainerIntegrationTest extends
BaseContainerIntegrationTest<AtmosStorageClient> {
BaseContainerIntegrationTest<AtmosStorageAsyncClient, AtmosStorageClient> {
@Override
@Test(enabled=false)
@Test(enabled = false)
// some reason this fails on the stub.
public void testClearWhenContentsUnderPath() throws Exception {
public void testClearWhenContentsUnderPath() throws InterruptedException {
super.testClearWhenContentsUnderPath();
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.atmosonline.saas.blobstore.integration;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
import org.testng.annotations.Test;
@ -31,6 +32,7 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "live" }, testName = "emcsaas.AtmosStorageContainerLiveTest")
public class AtmosStorageContainerLiveTest extends BaseContainerLiveTest<AtmosStorageClient> {
public class AtmosStorageContainerLiveTest extends
BaseContainerLiveTest<AtmosStorageAsyncClient, AtmosStorageClient> {
}

View File

@ -23,10 +23,10 @@
*/
package org.jclouds.atmosonline.saas.blobstore.integration;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest;
import org.testng.annotations.Test;
@ -36,7 +36,7 @@ import org.testng.annotations.Test;
*/
@Test(groups = { "integration", "live" }, testName = "emcsaas.AtmosStorageInputStreamMapIntegrationTest")
public class AtmosStorageInputStreamMapIntegrationTest extends
BaseInputStreamMapIntegrationTest<AtmosStorageClient> {
BaseInputStreamMapIntegrationTest<AtmosStorageAsyncClient, AtmosStorageClient> {
@Override
@Test(enabled = false)
@ -68,29 +68,25 @@ public class AtmosStorageInputStreamMapIntegrationTest extends
@Override
@Test(enabled = false)
public void testPut() throws IOException, InterruptedException, ExecutionException,
TimeoutException {
public void testPut() {
// TODO not reliable NPE@BaseInputStreamMapIntegrationTest.java:258
}
@Override
@Test(enabled = false)
public void testPutBytes() throws IOException, InterruptedException, ExecutionException,
TimeoutException {
public void testPutBytes() {
// TODO not reliable NPE
}
@Override
@Test(enabled = false)
public void testPutFile() throws IOException, InterruptedException, ExecutionException,
TimeoutException {
public void testPutFile() {
// TODO not reliable NPE
}
@Override
@Test(enabled = false)
public void testPutString() throws IOException, InterruptedException, ExecutionException,
TimeoutException {
public void testPutString() {
// TODO not reliable NPE
}

View File

@ -23,10 +23,7 @@
*/
package org.jclouds.atmosonline.saas.blobstore.integration;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
import org.testng.annotations.DataProvider;
@ -37,7 +34,8 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "integration", "live" }, testName = "emcsaas.AtmosStorageIntegrationTest")
public class AtmosStorageIntegrationTest extends BaseBlobIntegrationTest<AtmosStorageClient> {
public class AtmosStorageIntegrationTest extends
BaseBlobIntegrationTest<AtmosStorageAsyncClient, AtmosStorageClient> {
@DataProvider(name = "delete")
// no unicode support
@ -48,42 +46,37 @@ public class AtmosStorageIntegrationTest extends BaseBlobIntegrationTest<AtmosSt
@Override
@Test(enabled = false)
public void testGetIfMatch() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
public void testGetIfMatch() {
// no etag support
}
@Override
@Test(enabled = false)
public void testGetIfModifiedSince() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
public void testGetIfModifiedSince() {
// not supported
}
@Override
@Test(enabled = false)
public void testGetIfNoneMatch() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
public void testGetIfNoneMatch() {
// no etag support
}
@Override
@Test(enabled = false)
public void testGetIfUnmodifiedSince() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
public void testGetIfUnmodifiedSince() {
// not supported
}
@Override
@Test(enabled = false)
public void testGetTwoRanges() throws InterruptedException, ExecutionException,
TimeoutException, IOException {
public void testGetTwoRanges() {
// not supported
}
@Test(enabled = false)
// problem with the stub and md5, live is fine
public void testMetadata() throws Exception {
public void testMetadata() {
// TODO
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.atmosonline.saas.blobstore.integration;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
import org.testng.annotations.Test;
@ -32,6 +33,7 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "live" }, testName = "emcsaas.AtmosStorageLiveTest")
public class AtmosStorageLiveTest extends BaseBlobLiveTest<AtmosStorageClient> {
public class AtmosStorageLiveTest extends
BaseBlobLiveTest<AtmosStorageAsyncClient, AtmosStorageClient> {
}

View File

@ -26,6 +26,7 @@ package org.jclouds.atmosonline.saas.blobstore.integration;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest;
import org.testng.annotations.Test;
@ -34,7 +35,8 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "integration", "live" }, testName = "emcsaas.AtmosStorageMapIntegrationTest")
public class AtmosStorageMapIntegrationTest extends BaseBlobMapIntegrationTest<AtmosStorageClient> {
public class AtmosStorageMapIntegrationTest extends
BaseBlobMapIntegrationTest<AtmosStorageAsyncClient, AtmosStorageClient> {
@Override
@Test(enabled = false)

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.atmosonline.saas.blobstore.integration;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest;
import org.testng.annotations.Test;
@ -31,6 +32,7 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "integration", "live" }, testName = "emcsaas.AtmosStorageServiceIntegrationTest")
public class AtmosStorageServiceIntegrationTest extends BaseServiceIntegrationTest<AtmosStorageClient> {
public class AtmosStorageServiceIntegrationTest extends
BaseServiceIntegrationTest<AtmosStorageAsyncClient, AtmosStorageClient> {
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.atmosonline.saas.blobstore.integration;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.AtmosStoragePropertiesBuilder;
import org.jclouds.atmosonline.saas.blobstore.AtmosBlobStoreContextBuilder;
@ -38,20 +39,21 @@ import com.google.inject.Module;
*
* @author Adrian Cole
*/
public class AtmosStorageTestInitializer extends BaseTestInitializer<AtmosStorageClient> {
public class AtmosStorageTestInitializer extends
BaseTestInitializer<AtmosStorageAsyncClient, AtmosStorageClient> {
@Override
protected BlobStoreContext<AtmosStorageClient> createLiveContext(Module configurationModule,
String url, String app, String account, String key) {
return new AtmosBlobStoreContextBuilder(new AtmosStoragePropertiesBuilder(
account, key).relaxSSLHostname().build()).withModules(configurationModule,
protected BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient> createLiveContext(
Module configurationModule, String url, String app, String account, String key) {
return new AtmosBlobStoreContextBuilder(new AtmosStoragePropertiesBuilder(account, key)
.relaxSSLHostname().build()).withModules(configurationModule,
new Log4JLoggingModule()).buildContext();
}
@Override
protected BlobStoreContext<AtmosStorageClient> createStubContext() {
protected BlobStoreContext<AtmosStorageAsyncClient, AtmosStorageClient> createStubContext() {
return AtmosBlobStoreContextFactory.createContext("user", "pass",
new AtmosStorageStubClientModule());
new AtmosStorageStubClientModule());
}
}

View File

@ -25,13 +25,18 @@ package org.jclouds.atmosonline.saas.config;
import java.net.URI;
import javax.inject.Singleton;
import org.jclouds.atmosonline.saas.AtmosStorage;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.internal.StubAtmosStorageClient;
import org.jclouds.atmosonline.saas.internal.StubAtmosStorageAsyncClient;
import org.jclouds.blobstore.integration.config.StubBlobStoreModule;
import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.rest.ConfiguresRestClient;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* adds a stub alternative to invoking AtmosStorage
@ -43,7 +48,15 @@ public class AtmosStorageStubClientModule extends AbstractModule {
protected void configure() {
install(new StubBlobStoreModule());
bind(AtmosStorageClient.class).to(StubAtmosStorageClient.class).asEagerSingleton();
bind(URI.class).annotatedWith(AtmosStorage.class).toInstance(URI.create("https://localhost/azurestub"));
bind(AtmosStorageAsyncClient.class).to(StubAtmosStorageAsyncClient.class).asEagerSingleton();
bind(URI.class).annotatedWith(AtmosStorage.class).toInstance(
URI.create("https://localhost/azurestub"));
}
@Provides
@Singleton
public AtmosStorageClient provideClient(AtmosStorageAsyncClient client)
throws IllegalArgumentException, SecurityException, NoSuchMethodException {
return SyncProxy.create(AtmosStorageClient.class, client);
}
}

View File

@ -26,11 +26,12 @@ package org.jclouds.atmosonline.saas.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.inject.Inject;
import org.jclouds.atmosonline.saas.AtmosStorageClient;
import org.jclouds.atmosonline.saas.AtmosStorageAsyncClient;
import org.jclouds.atmosonline.saas.blobstore.functions.BlobMetadataToObject;
import org.jclouds.atmosonline.saas.blobstore.functions.BlobToObject;
import org.jclouds.atmosonline.saas.blobstore.functions.ListOptionsToBlobStoreListOptions;
@ -48,7 +49,8 @@ import org.jclouds.blobstore.attr.ConsistencyModels;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions;
import org.jclouds.blobstore.integration.internal.StubBlobStore;
import org.jclouds.blobstore.integration.internal.StubAsyncBlobStore;
import org.jclouds.blobstore.integration.internal.StubAsyncBlobStore.FutureBase;
import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory;
@ -57,14 +59,14 @@ import org.jclouds.util.Utils;
import com.google.common.base.Function;
/**
* Implementation of {@link AtmosStorageClient} which keeps all data in a local Map object.
* Implementation of {@link AtmosStorageAsyncClient} which keeps all data in a local Map object.
*
* @author Adrian Cole
*/
@ConsistencyModel(ConsistencyModels.STRICT)
public class StubAtmosStorageClient implements AtmosStorageClient {
public class StubAtmosStorageAsyncClient implements AtmosStorageAsyncClient {
private final HttpGetOptionsListToGetOptions httpGetOptionsConverter;
private final StubBlobStore blobStore;
private final StubAsyncBlobStore blobStore;
private final LoggerFactory logFactory;
private final AtmosObject.Factory objectProvider;
private final ObjectToBlob object2Blob;
@ -74,7 +76,7 @@ public class StubAtmosStorageClient implements AtmosStorageClient {
private final ResourceMetadataListToDirectoryEntryList resource2ObjectList;
@Inject
private StubAtmosStorageClient(StubBlobStore blobStore, LoggerFactory logFactory,
private StubAtmosStorageAsyncClient(StubAsyncBlobStore blobStore, LoggerFactory logFactory,
AtmosObject.Factory objectProvider,
HttpGetOptionsListToGetOptions httpGetOptionsConverter, ObjectToBlob object2Blob,
BlobToObject blob2Object, BlobMetadataToObject blob2ObjectInfo,
@ -124,14 +126,13 @@ public class StubAtmosStorageClient implements AtmosStorageClient {
object.getContentMetadata().setName(path + "/" + file);
}
Blob blob = object2Blob.apply(object);
return wrapFuture(blobStore.putBlob(container, blob),
new Function<String, URI>() {
return wrapFuture(blobStore.putBlob(container, blob), new Function<String, URI>() {
public URI apply(String from) {
return URI.create(uri);
}
public URI apply(String from) {
return URI.create(uri);
}
});
});
}
public Future<Void> deletePath(String path) {
@ -150,31 +151,30 @@ public class StubAtmosStorageClient implements AtmosStorageClient {
}
}
public SystemMetadata getSystemMetadata(String path) {
public Future<SystemMetadata> getSystemMetadata(String path) {
throw new UnsupportedOperationException();
}
public UserMetadata getUserMetadata(String path) {
public Future<UserMetadata> getUserMetadata(String path) {
if (path.indexOf('/') == -1)
throw new UnsupportedOperationException();
else {
String container = path.substring(0, path.indexOf('/'));
path = path.substring(path.indexOf('/') + 1);
return new Function<BlobMetadata, UserMetadata>() {
public UserMetadata apply(BlobMetadata from) {
return blob2ObjectInfo.apply(from).getUserMetadata();
}
}.apply(blobStore.blobMetadata(container, path));
return wrapFuture(blobStore.blobMetadata(container, path),
new Function<BlobMetadata, UserMetadata>() {
public UserMetadata apply(BlobMetadata from) {
return blob2ObjectInfo.apply(from).getUserMetadata();
}
});
}
}
public AtmosObject headFile(String path) {
public Future<AtmosObject> headFile(String path) {
String container = path.substring(0, path.indexOf('/'));
path = path.substring(path.indexOf('/') + 1);
try {
return this.blob2Object.apply(blobStore.getBlob(container, path).get());
return wrapFuture(blobStore.getBlob(container, path), blob2Object);
} catch (Exception e) {
Utils.<KeyNotFoundException> rethrowIfRuntimeOrSameType(e);
throw new RuntimeException(e);
@ -206,18 +206,23 @@ public class StubAtmosStorageClient implements AtmosStorageClient {
return this.objectProvider.create(null);
}
public boolean pathExists(String path) {
public Future<Boolean> pathExists(final String path) {
if (path.indexOf('/') == -1 || (path.endsWith("/")))
return blobStore.exists(path);
else {
String container = path.substring(0, path.indexOf('/'));
String blobName = path.substring(path.indexOf('/') + 1);
try {
blobStore.blobMetadata(container, blobName);
return true;
} catch (KeyNotFoundException e) {
return false;
}
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException, ExecutionException {
String container = path.substring(0, path.indexOf('/'));
String blobName = path.substring(path.indexOf('/') + 1);
try {
blobStore.blobMetadata(container, blobName);
return true;
} catch (KeyNotFoundException e) {
return false;
}
}
};
}
}

View File

@ -0,0 +1,295 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2;
import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION;
import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION;
import java.net.InetAddress;
import java.util.SortedSet;
import java.util.concurrent.Future;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.ec2.binders.BindGroupNameToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindInetAddressesToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindInstanceIdsToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindKeyNameToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams;
import org.jclouds.aws.ec2.domain.Image;
import org.jclouds.aws.ec2.domain.ImageAttribute;
import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.SecurityGroup;
import org.jclouds.aws.ec2.domain.TerminatedInstance;
import org.jclouds.aws.ec2.domain.UserIdGroupPair;
import org.jclouds.aws.ec2.filters.FormSigner;
import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound;
import org.jclouds.aws.ec2.options.DescribeImagesOptions;
import org.jclouds.aws.ec2.options.RunInstancesOptions;
import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeSecurityGroupsResponseHandler;
import org.jclouds.aws.ec2.xml.KeyPairResponseHandler;
import org.jclouds.aws.ec2.xml.RunInstancesResponseHandler;
import org.jclouds.aws.ec2.xml.TerminateInstancesResponseHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.InetAddressToHostAddress;
/**
* Provides access to EC2 via their REST API.
* <p/>
*
* @author Adrian Cole
*/
@Endpoint(EC2.class)
@RequestFilters(FormSigner.class)
@FormParams(keys = VERSION, values = "2009-08-15")
@VirtualHost
public interface EC2AsyncClient {
/**
* @see EC2Client#describeImages
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeImages")
@XMLResponseParser(DescribeImagesResponseHandler.class)
Future<? extends SortedSet<Image>> describeImages(DescribeImagesOptions... options);
/**
* Returns information about an attribute of an AMI. Only one attribute can be specified per
* call.
*
* @param imageId
* The ID of the AMI for which an attribute will be described
* @param attribute
* the attribute to describe
* @see #describeImages
* @see #modifyImageAttribute
* @see #resetImageAttribute
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeImageAttribute.html"
* />
* @see DescribeImagesOptions
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeImageAttribute")
Future<String> describeImageAttribute(@FormParam("ImageId") String imageId,
@FormParam("Attribute") ImageAttribute attribute);
/**
* Acquires an elastic IP address for use with your account.
*
* @see #describeAddresses
* @see #releaseAddress
* @see #associateAddress
* @see #disassociateAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AllocateAddress.html"
*/
@POST
@Path("/")
@XMLResponseParser(AllocateAddressResponseHandler.class)
@FormParams(keys = ACTION, values = "AllocateAddress")
Future<InetAddress> allocateAddress();
/**
* @see EC2Client#associateAddress
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "AssociateAddress")
Future<Void> associateAddress(
@FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp,
@FormParam("InstanceId") String instanceId);
/**
* @see EC2Client#disassociateAddress
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DisassociateAddress")
Future<Void> disassociateAddress(
@FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp);
/**
* @see EC2Client#releaseAddress
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "ReleaseAddress")
Future<Void> releaseAddress(
@FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp);
/**
* @see EC2Client#describeAddresses
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeAddresses")
@XMLResponseParser(DescribeAddressesResponseHandler.class)
Future<? extends SortedSet<PublicIpInstanceIdPair>> describeAddresses(
@BinderParam(BindInetAddressesToIndexedFormParams.class) InetAddress... publicIps);
/**
* @see EC2Client#describeInstances
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeInstances")
@XMLResponseParser(DescribeInstancesResponseHandler.class)
Future<? extends SortedSet<Reservation>> describeInstances(
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/**
* @see EC2Client#runInstances
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RunInstances")
@XMLResponseParser(RunInstancesResponseHandler.class)
Future<Reservation> runInstances(@FormParam("ImageId") String imageId,
@FormParam("MinCount") int minCount, @FormParam("MaxCount") int maxCount,
RunInstancesOptions... options);
/**
* @see EC2Client#terminateInstances
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "TerminateInstances")
@XMLResponseParser(TerminateInstancesResponseHandler.class)
Future<? extends SortedSet<TerminatedInstance>> terminateInstances(
@FormParam("InstanceId.0") String instanceId,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
/**
* @see EC2Client#createKeyPair
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "CreateKeyPair")
@XMLResponseParser(KeyPairResponseHandler.class)
Future<KeyPair> createKeyPair(@FormParam("KeyName") String keyName);
/**
* @see EC2Client#describeKeyPairs
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeKeyPairs")
@XMLResponseParser(DescribeKeyPairsResponseHandler.class)
Future<? extends SortedSet<KeyPair>> describeKeyPairs(
@BinderParam(BindKeyNameToIndexedFormParams.class) String... keyPairNames);
/**
* @see EC2Client#deleteKeyPair
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DeleteKeyPair")
Future<Void> deleteKeyPair(@FormParam("KeyName") String keyName);
/**
* @see EC2Client#createSecurityGroup
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "CreateSecurityGroup")
Future<Void> createSecurityGroup(@FormParam("GroupName") String name,
@FormParam("GroupDescription") String description);
/**
* @see EC2Client#deleteSecurityGroup
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DeleteSecurityGroup")
@ExceptionParser(ReturnVoidOnGroupNotFound.class)
Future<Void> deleteSecurityGroup(@FormParam("GroupName") String name);
/**
* @see EC2Client#describeSecurityGroups
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeSecurityGroups")
@XMLResponseParser(DescribeSecurityGroupsResponseHandler.class)
Future<? extends SortedSet<SecurityGroup>> describeSecurityGroups(
@BinderParam(BindGroupNameToIndexedFormParams.class) String... securityGroupNames);
/**
* @see EC2Client#authorizeSecurityGroupIngress(String,UserIdGroupPair)
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
Future<Void> authorizeSecurityGroupIngress(
@FormParam("GroupName") String groupName,
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
/**
* @see EC2Client#authorizeSecurityGroupIngress(String,IpProtocol,int,int,String)
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
Future<Void> authorizeSecurityGroupIngress(@FormParam("GroupName") String groupName,
@FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort,
@FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp);
/**
* @see EC2Client#revokeSecurityGroupIngress(String,UserIdGroupPair)
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
Future<Void> revokeSecurityGroupIngress(
@FormParam("GroupName") String groupName,
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
/**
* @see EC2Client#revokeSecurityGroupIngress(String,IpProtocol,int,int,String)
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
Future<Void> revokeSecurityGroupIngress(@FormParam("GroupName") String groupName,
@FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort,
@FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp);
}

View File

@ -23,22 +23,11 @@
*/
package org.jclouds.aws.ec2;
import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION;
import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION;
import java.net.InetAddress;
import java.util.SortedSet;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.ec2.binders.BindGroupNameToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindInetAddressesToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindInstanceIdsToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindKeyNameToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindUserIdGroupPairToSourceSecurityGroupFormParams;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.ec2.domain.Image;
import org.jclouds.aws.ec2.domain.ImageAttribute;
import org.jclouds.aws.ec2.domain.IpProtocol;
@ -48,28 +37,9 @@ import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.SecurityGroup;
import org.jclouds.aws.ec2.domain.TerminatedInstance;
import org.jclouds.aws.ec2.domain.UserIdGroupPair;
import org.jclouds.aws.ec2.filters.FormSigner;
import org.jclouds.aws.ec2.functions.ReturnVoidOnGroupNotFound;
import org.jclouds.aws.ec2.options.DescribeImagesOptions;
import org.jclouds.aws.ec2.options.RunInstancesOptions;
import org.jclouds.aws.ec2.xml.AllocateAddressResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeAddressesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeInstancesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeKeyPairsResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeSecurityGroupsResponseHandler;
import org.jclouds.aws.ec2.xml.KeyPairResponseHandler;
import org.jclouds.aws.ec2.xml.RunInstancesResponseHandler;
import org.jclouds.aws.ec2.xml.TerminateInstancesResponseHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.InetAddressToHostAddress;
import org.jclouds.concurrent.Timeout;
/**
* Provides access to EC2 via their REST API.
@ -77,10 +47,7 @@ import org.jclouds.rest.functions.InetAddressToHostAddress;
*
* @author Adrian Cole
*/
@Endpoint(EC2.class)
@RequestFilters(FormSigner.class)
@FormParams(keys = VERSION, values = "2009-08-15")
@VirtualHost
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface EC2Client {
/**
@ -95,11 +62,7 @@ public interface EC2Client {
* />
* @see DescribeImagesOptions
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeImages")
@XMLResponseParser(DescribeImagesResponseHandler.class)
Future<? extends SortedSet<Image>> describeImages(DescribeImagesOptions... options);
SortedSet<Image> describeImages(DescribeImagesOptions... options);
/**
* Returns information about an attribute of an AMI. Only one attribute can be specified per
@ -116,11 +79,7 @@ public interface EC2Client {
* />
* @see DescribeImagesOptions
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeImageAttribute")
String describeImageAttribute(@FormParam("ImageId") String imageId,
@FormParam("Attribute") ImageAttribute attribute);
String describeImageAttribute(String imageId, ImageAttribute attribute);
/**
* Acquires an elastic IP address for use with your account.
@ -131,11 +90,7 @@ public interface EC2Client {
* @see #disassociateAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AllocateAddress.html"
*/
@POST
@Path("/")
@XMLResponseParser(AllocateAddressResponseHandler.class)
@FormParams(keys = ACTION, values = "AllocateAddress")
Future<InetAddress> allocateAddress();
InetAddress allocateAddress();
/**
* Associates an elastic IP address with an instance. If the IP address is currently assigned to
@ -153,12 +108,7 @@ public interface EC2Client {
* @see #disassociateAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-AssociateAddress.html"
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "AssociateAddress")
Future<Void> associateAddress(
@FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp,
@FormParam("InstanceId") String instanceId);
void associateAddress(InetAddress publicIp, String instanceId);
/**
* Disassociates the specified elastic IP address from the instance to which it is assigned. This
@ -174,11 +124,7 @@ public interface EC2Client {
* @see #associateAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-DisdisassociateAddress.html"
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DisassociateAddress")
Future<Void> disassociateAddress(
@FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp);
void disassociateAddress(InetAddress publicIp);
/**
* Releases an elastic IP address associated with your account.
@ -191,11 +137,7 @@ public interface EC2Client {
* @see #disassociateAddress
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-query-ReleaseAddress.html"
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "ReleaseAddress")
Future<Void> releaseAddress(
@FormParam("PublicIp") @ParamParser(InetAddressToHostAddress.class) InetAddress publicIp);
void releaseAddress(InetAddress publicIp);
/**
* Lists elastic IP addresses assigned to your account or provides information about a specific
@ -210,12 +152,7 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeAddresses.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeAddresses")
@XMLResponseParser(DescribeAddressesResponseHandler.class)
Future<? extends SortedSet<PublicIpInstanceIdPair>> describeAddresses(
@BinderParam(BindInetAddressesToIndexedFormParams.class) InetAddress... publicIps);
SortedSet<PublicIpInstanceIdPair> describeAddresses(InetAddress... publicIps);
/**
* Returns information about instances that you own.
@ -234,12 +171,7 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeInstances")
@XMLResponseParser(DescribeInstancesResponseHandler.class)
Future<? extends SortedSet<Reservation>> describeInstances(
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
SortedSet<Reservation> describeInstances(String... instanceIds);
/**
* Launches a specified number of instances of an AMI for which you have permissions.
@ -305,12 +237,7 @@ public interface EC2Client {
* />
* @see RunInstancesOptions
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RunInstances")
@XMLResponseParser(RunInstancesResponseHandler.class)
Future<Reservation> runInstances(@FormParam("ImageId") String imageId,
@FormParam("MinCount") int minCount, @FormParam("MaxCount") int maxCount,
Reservation runInstances(String imageId, int minCount, int maxCount,
RunInstancesOptions... options);
/**
@ -325,13 +252,7 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-TerminateInstances.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "TerminateInstances")
@XMLResponseParser(TerminateInstancesResponseHandler.class)
Future<? extends SortedSet<TerminatedInstance>> terminateInstances(
@FormParam("InstanceId.0") String instanceId,
@BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds);
SortedSet<TerminatedInstance> terminateInstances(String instanceId, String... instanceIds);
/**
* Creates a new 2048-bit RSA key pair with the specified name. The public key is stored by
@ -347,11 +268,7 @@ public interface EC2Client {
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateKeyPair.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "CreateKeyPair")
@XMLResponseParser(KeyPairResponseHandler.class)
Future<KeyPair> createKeyPair(@FormParam("KeyName") String keyName);
KeyPair createKeyPair(String keyName);
/**
* Returns information about key pairs available to you. If you specify key pairs, information
@ -365,12 +282,7 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeKeyPairs.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeKeyPairs")
@XMLResponseParser(DescribeKeyPairsResponseHandler.class)
Future<? extends SortedSet<KeyPair>> describeKeyPairs(
@BinderParam(BindKeyNameToIndexedFormParams.class) String... keyPairNames);
SortedSet<KeyPair> describeKeyPairs(String... keyPairNames);
/**
* Deletes the specified key pair, by removing the public key from Amazon EC2. You must own the
@ -383,10 +295,8 @@ public interface EC2Client {
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteKeyPair.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DeleteKeyPair")
Future<Void> deleteKeyPair(@FormParam("KeyName") String keyName);
void deleteKeyPair(String keyName);
/**
* Creates a new security group. Group names must be unique per account.
@ -407,11 +317,7 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateSecurityGroup.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "CreateSecurityGroup")
Future<Void> createSecurityGroup(@FormParam("GroupName") String name,
@FormParam("GroupDescription") String description);
void createSecurityGroup(String name, String description);
/**
* Deletes a security group that you own.
@ -427,11 +333,7 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSecurityGroup.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DeleteSecurityGroup")
@ExceptionParser(ReturnVoidOnGroupNotFound.class)
Future<Void> deleteSecurityGroup(@FormParam("GroupName") String name);
void deleteSecurityGroup(String name);
/**
* Returns information about security groups that you own.
@ -447,12 +349,7 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSecurityGroups.html"
* />
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeSecurityGroups")
@XMLResponseParser(DescribeSecurityGroupsResponseHandler.class)
Future<? extends SortedSet<SecurityGroup>> describeSecurityGroups(
@BinderParam(BindGroupNameToIndexedFormParams.class) String... securityGroupNames);
SortedSet<SecurityGroup> describeSecurityGroups(String... securityGroupNames);
/**
*
@ -471,12 +368,7 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AuthorizeSecurityGroupIngress.html"
*
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
Future<Void> authorizeSecurityGroupIngress(
@FormParam("GroupName") String groupName,
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
void authorizeSecurityGroupIngress(String groupName, UserIdGroupPair sourceSecurityGroup);
/**
*
@ -510,12 +402,8 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AuthorizeSecurityGroupIngress.html"
*
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "AuthorizeSecurityGroupIngress")
Future<Void> authorizeSecurityGroupIngress(@FormParam("GroupName") String groupName,
@FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort,
@FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp);
void authorizeSecurityGroupIngress(String groupName, IpProtocol ipProtocol, int fromPort,
int toPort, String cidrIp);
/**
*
@ -535,12 +423,7 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RevokeSecurityGroupIngress.html"
*
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
Future<Void> revokeSecurityGroupIngress(
@FormParam("GroupName") String groupName,
@BinderParam(BindUserIdGroupPairToSourceSecurityGroupFormParams.class) UserIdGroupPair sourceSecurityGroup);
void revokeSecurityGroupIngress(String groupName, UserIdGroupPair sourceSecurityGroup);
/**
*
@ -575,10 +458,6 @@ public interface EC2Client {
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-RevokeSecurityGroupIngress.html"
*
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "RevokeSecurityGroupIngress")
Future<Void> revokeSecurityGroupIngress(@FormParam("GroupName") String groupName,
@FormParam("IpProtocol") IpProtocol ipProtocol, @FormParam("FromPort") int fromPort,
@FormParam("ToPort") int toPort, @FormParam("CidrIp") String cidrIp);
void revokeSecurityGroupIngress(String groupName, IpProtocol ipProtocol, int fromPort,
int toPort, String cidrIp);
}

View File

@ -41,10 +41,11 @@ import com.google.inject.TypeLiteral;
*
* @author Adrian Cole
*/
public class EC2ContextBuilder extends RestContextBuilder<EC2Client> {
public class EC2ContextBuilder extends RestContextBuilder<EC2AsyncClient, EC2Client> {
public EC2ContextBuilder(Properties props) {
super(new TypeLiteral<EC2Client>() {
super(new TypeLiteral<EC2AsyncClient>() {
}, new TypeLiteral<EC2Client>() {
}, props);
checkNotNull(properties.getProperty(PROPERTY_AWS_ACCESSKEYID));
checkNotNull(properties.getProperty(PROPERTY_AWS_SECRETACCESSKEY));

View File

@ -33,8 +33,8 @@ import org.jclouds.rest.RestContext;
import com.google.inject.Module;
/**
* Creates {@link RestContext} instances bound with generic type {@link EC2Client} based on the most
* commonly requested arguments.
* Creates {@link RestContext} instances bound with generic type {@link EC2AsyncClient} based on the
* most commonly requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
@ -46,19 +46,20 @@ import com.google.inject.Module;
* @see RestContext
*/
public class EC2ContextFactory {
public static RestContext<EC2Client> createContext(Properties properties, Module... modules) {
public static RestContext<EC2AsyncClient, EC2Client> createContext(Properties properties,
Module... modules) {
return new EC2ContextBuilder(new EC2PropertiesBuilder(properties).build()).withModules(
modules).buildContext();
}
public static RestContext<EC2Client> createContext(String awsAccessKeyId,
public static RestContext<EC2AsyncClient, EC2Client> createContext(String awsAccessKeyId,
String awsSecretAccessKey, Module... modules) {
return new EC2ContextBuilder(new EC2PropertiesBuilder(awsAccessKeyId, awsSecretAccessKey)
.build()).withModules(modules).buildContext();
}
public static RestContext<EC2Client> createContext(URI endpoint, String awsAccessKeyId,
String awsSecretAccessKey, Module... modules) {
public static RestContext<EC2AsyncClient, EC2Client> createContext(URI endpoint,
String awsAccessKeyId, String awsSecretAccessKey, Module... modules) {
return new EC2ContextBuilder(new EC2PropertiesBuilder(awsAccessKeyId, awsSecretAccessKey)
.withEndpoint(endpoint).build()).withModules(modules).buildContext();
}

View File

@ -29,6 +29,7 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.reference.AWSConstants;
import org.jclouds.http.functions.config.ParserModule.CDateTimeAdapter;
@ -53,9 +54,11 @@ public class EC2ContextModule extends AbstractModule {
@Provides
@Singleton
RestContext<EC2Client> provideContext(Closer closer, EC2Client defaultApi, @EC2 URI endPoint,
RestContext<EC2AsyncClient, EC2Client> provideContext(Closer closer, EC2AsyncClient defaultApi,
EC2Client synchApi, @EC2 URI endPoint,
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
return new RestContextImpl<EC2Client>(closer, defaultApi, endPoint, account);
return new RestContextImpl<EC2AsyncClient, EC2Client>(closer, defaultApi, synchApi, endPoint,
account);
}
}

View File

@ -29,6 +29,7 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.filters.FormSigner;
import org.jclouds.aws.ec2.reference.EC2Constants;
@ -36,6 +37,7 @@ import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.aws.util.RequestSigner;
import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
@ -81,8 +83,15 @@ public class EC2RestClientModule extends AbstractModule {
@Provides
@Singleton
protected EC2Client provideClient(RestClientFactory factory) {
return factory.create(EC2Client.class);
protected EC2AsyncClient provideAsyncClient(RestClientFactory factory) {
return factory.create(EC2AsyncClient.class);
}
@Provides
@Singleton
public EC2Client provideClient(EC2AsyncClient client) throws IllegalArgumentException,
SecurityException, NoSuchMethodException {
return SyncProxy.create(EC2Client.class, client);
}
@Provides

View File

@ -1,15 +1,15 @@
package org.jclouds.aws.ec2.domain;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.EC2AsyncClient;
/**
*
* An attribute of an AMI.
*
* @author Adrian Cole
* @see EC2Client#modifyImageAttribute
* @see EC2Client#resetImageAttribute
* @see EC2Client#describeImageAttribute
* @see EC2AsyncClient#modifyImageAttribute
* @see EC2AsyncClient#resetImageAttribute
* @see EC2AsyncClient#describeImageAttribute
*
*/
public enum ImageAttribute {

View File

@ -2,16 +2,16 @@ package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.EC2AsyncClient;
/**
*
* The current state of the instance..
*
* @author Adrian Cole
* @see EC2Client#describeInstances
* @see EC2Client#runInstances
* @see EC2Client#terminateInstances
* @see EC2AsyncClient#describeInstances
* @see EC2AsyncClient#runInstances
* @see EC2AsyncClient#terminateInstances
*
*/
public enum InstanceState {

View File

@ -2,16 +2,16 @@ package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.EC2AsyncClient;
/**
*
* The type of the instance. Description accurate as of 8-15-2009 release.
*
* @author Adrian Cole
* @see EC2Client#describeInstances
* @see EC2Client#runInstances
* @see EC2Client#terminateInstances
* @see EC2AsyncClient#describeInstances
* @see EC2AsyncClient#runInstances
* @see EC2AsyncClient#terminateInstances
*
*/
public enum InstanceType {

View File

@ -0,0 +1,239 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3;
import static org.jclouds.blobstore.attr.BlobScopes.CONTAINER;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.aws.s3.binders.BindACLToXMLEntity;
import org.jclouds.aws.s3.binders.BindS3ObjectToEntity;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.functions.ObjectKey;
import org.jclouds.aws.s3.functions.ParseObjectFromHeadersAndHttpContent;
import org.jclouds.aws.s3.functions.ParseObjectMetadataFromHeaders;
import org.jclouds.aws.s3.functions.ReturnTrueIfBucketAlreadyOwnedByYou;
import org.jclouds.aws.s3.functions.ReturnTrueOn404FalseIfNotEmpty;
import org.jclouds.aws.s3.options.CopyObjectOptions;
import org.jclouds.aws.s3.options.ListBucketOptions;
import org.jclouds.aws.s3.options.PutBucketOptions;
import org.jclouds.aws.s3.options.PutObjectOptions;
import org.jclouds.aws.s3.xml.AccessControlListHandler;
import org.jclouds.aws.s3.xml.CopyObjectHandler;
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
import org.jclouds.aws.s3.xml.ListBucketHandler;
import org.jclouds.blobstore.attr.BlobScope;
import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.attr.ConsistencyModels;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ParseETagHeader;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.http.options.GetOptions;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.HostPrefixParam;
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.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
/**
* Provides asynchronous access to S3 via their REST API.
* <p/>
* All commands return a Future of the result from S3. Any exceptions incurred during processing
* will be wrapped in an {@link ExecutionException} as documented in {@link Future#get()}.
*
* @author Adrian Cole
* @author James Murty
* @see S3Client
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
*/
@VirtualHost
@SkipEncoding('/')
@RequestFilters(RequestAuthorizeSignature.class)
@Endpoint(S3.class)
@BlobScope(CONTAINER)
@ConsistencyModel(ConsistencyModels.EVENTUAL)
public interface S3AsyncClient {
/**
* Creates a default implementation of S3Object
*/
public S3Object newS3Object();
/**
* @see S3Client#getObject
*/
@GET
@Path("{key}")
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
Future<S3Object> getObject(@HostPrefixParam String bucketName, @PathParam("key") String key,
GetOptions... options);
/**
* @see S3Client#headObject
*/
@HEAD
@Path("{key}")
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@ResponseParser(ParseObjectMetadataFromHeaders.class)
Future<ObjectMetadata> headObject(@HostPrefixParam String bucketName,
@PathParam("key") String key);
/**
* @see S3Client#deleteObject
*/
@DELETE
@Path("{key}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
Future<Void> deleteObject(@HostPrefixParam String bucketName, @PathParam("key") String key);
/**
* @see S3Client#putObject
*/
@PUT
@Path("{key}")
@ResponseParser(ParseETagHeader.class)
Future<String> putObject(
@HostPrefixParam String bucketName,
@PathParam("key") @ParamParser(ObjectKey.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object,
PutObjectOptions... options);
/**
* @see S3Client#putBucketIfNotExists
*/
@PUT
@Path("/")
@ExceptionParser(ReturnTrueIfBucketAlreadyOwnedByYou.class)
Future<Boolean> putBucketIfNotExists(@HostPrefixParam String bucketName,
PutBucketOptions... options);
/**
* @see S3Client#deleteBucketIfEmpty
*/
@DELETE
@Path("/")
@ExceptionParser(ReturnTrueOn404FalseIfNotEmpty.class)
Future<Boolean> deleteBucketIfEmpty(@HostPrefixParam String bucketName);
/**
* @see S3Client#bucketExists
*/
@HEAD
@Path("/")
@QueryParams(keys = "max-keys", values = "0")
@ExceptionParser(ReturnFalseOn404.class)
Future<Boolean> bucketExists(@HostPrefixParam String bucketName);
/**
* @see S3Client#listBucket
*/
@GET
@Path("/")
@XMLResponseParser(ListBucketHandler.class)
Future<ListBucketResponse> listBucket(@HostPrefixParam String bucketName,
ListBucketOptions... options);
/**
* @see S3Client#listOwnedBuckets
*/
@GET
@XMLResponseParser(ListAllMyBucketsHandler.class)
@Path("/")
Future<? extends SortedSet<BucketMetadata>> listOwnedBuckets();
/**
* @see S3Client#copyObject
*/
@PUT
@Path("{destinationObject}")
@Headers(keys = "x-amz-copy-source", values = "/{sourceBucket}/{sourceObject}")
@XMLResponseParser(CopyObjectHandler.class)
Future<ObjectMetadata> copyObject(@PathParam("sourceBucket") String sourceBucket,
@PathParam("sourceObject") String sourceObject,
@HostPrefixParam String destinationBucket,
@PathParam("destinationObject") String destinationObject, CopyObjectOptions... options);
/**
* @see S3Client#getBucketACL
*/
@GET
@QueryParams(keys = "acl")
@XMLResponseParser(AccessControlListHandler.class)
@ExceptionParser(ThrowContainerNotFoundOn404.class)
@Path("/")
Future<AccessControlList> getBucketACL(@HostPrefixParam String bucketName);
/**
* @see S3Client#putBucketACL
*/
@PUT
@Path("/")
@QueryParams(keys = "acl")
Future<Boolean> putBucketACL(@HostPrefixParam String bucketName,
@BinderParam(BindACLToXMLEntity.class) AccessControlList acl);
/**
* @see S3Client#getObjectACL
*/
@GET
@QueryParams(keys = "acl")
@Path("{key}")
@XMLResponseParser(AccessControlListHandler.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
Future<AccessControlList> getObjectACL(@HostPrefixParam String bucketName,
@PathParam("key") String key);
/**
* @see S3Client#putObjectACL
*/
@PUT
@QueryParams(keys = "acl")
@Path("{key}")
Future<Boolean> putObjectACL(@HostPrefixParam String bucketName, @PathParam("key") String key,
@BinderParam(BindACLToXMLEntity.class) AccessControlList acl);
}

View File

@ -23,59 +23,22 @@
*/
package org.jclouds.aws.s3;
import static org.jclouds.blobstore.attr.BlobScopes.CONTAINER;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.aws.s3.binders.BindACLToXMLEntity;
import org.jclouds.aws.s3.binders.BindS3ObjectToEntity;
import org.jclouds.aws.s3.domain.AccessControlList;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.functions.ObjectKey;
import org.jclouds.aws.s3.functions.ParseObjectFromHeadersAndHttpContent;
import org.jclouds.aws.s3.functions.ParseObjectMetadataFromHeaders;
import org.jclouds.aws.s3.functions.ReturnTrueIfBucketAlreadyOwnedByYou;
import org.jclouds.aws.s3.functions.ReturnTrueOn404FalseIfNotEmpty;
import org.jclouds.aws.s3.options.CopyObjectOptions;
import org.jclouds.aws.s3.options.ListBucketOptions;
import org.jclouds.aws.s3.options.PutBucketOptions;
import org.jclouds.aws.s3.options.PutObjectOptions;
import org.jclouds.aws.s3.xml.AccessControlListHandler;
import org.jclouds.aws.s3.xml.CopyObjectHandler;
import org.jclouds.aws.s3.xml.ListAllMyBucketsHandler;
import org.jclouds.aws.s3.xml.ListBucketHandler;
import org.jclouds.blobstore.attr.BlobScope;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ParseETagHeader;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.concurrent.Timeout;
import org.jclouds.http.options.GetOptions;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.HostPrefixParam;
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.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
/**
* Provides access to S3 via their REST API.
@ -87,11 +50,7 @@ import org.jclouds.rest.annotations.XMLResponseParser;
* @author James Murty
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAPI.html" />
*/
@VirtualHost
@SkipEncoding('/')
@RequestFilters(RequestAuthorizeSignature.class)
@Endpoint(S3.class)
@BlobScope(CONTAINER)
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface S3Client {
/**
@ -109,7 +68,7 @@ public interface S3Client {
* <p />
* This command allows you to specify {@link GetObjectOptions} to control delivery of content.
*
* <h2>Note</h2> If you specify any of the below options, you will receive partial content:
* <h2>Note</h2 If you specify any of the below options, you will receive partial content:
* <ul>
* <li>{@link GetObjectOptions#range}</li>
* <li>{@link GetObjectOptions#startAt}</li>
@ -128,12 +87,7 @@ public interface S3Client {
* @see #getObject(String, String)
* @see GetObjectOptions
*/
@GET
@Path("{key}")
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
Future<S3Object> getObject(@HostPrefixParam String bucketName, @PathParam("key") String key,
GetOptions... options);
S3Object getObject(String bucketName, String key, GetOptions... options);
/**
* Retrieves the {@link org.jclouds.aws.s3.domain.internal.BucketListObjectMetadata metadata} of
@ -159,11 +113,7 @@ public interface S3Client {
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectHEAD.html"
* />
*/
@HEAD
@Path("{key}")
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@ResponseParser(ParseObjectMetadataFromHeaders.class)
ObjectMetadata headObject(@HostPrefixParam String bucketName, @PathParam("key") String key);
ObjectMetadata headObject(String bucketName, String key);
/**
* Removes the object and metadata associated with the key.
@ -182,15 +132,12 @@ public interface S3Client {
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?
* RESTObjectDELETE.html" />
*/
@DELETE
@Path("{key}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
Future<Void> deleteObject(@HostPrefixParam String bucketName, @PathParam("key") String key);
void deleteObject(String bucketName, String key);
/**
* Store data by creating or overwriting an object.
* <p/>
* This method will store the object with the default <code>private</code> acl.
* This method will store the object with the default <code>private</code acl.
*
* <p/>
* This returns a byte[] of the eTag hash of what Amazon S3 received
@ -210,13 +157,7 @@ public interface S3Client {
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTObjectPUT.html"
* />
*/
@PUT
@Path("{key}")
@ResponseParser(ParseETagHeader.class)
Future<String> putObject(
@HostPrefixParam String bucketName,
@PathParam("key") @ParamParser(ObjectKey.class) @BinderParam(BindS3ObjectToEntity.class) S3Object object,
PutObjectOptions... options);
String putObject(String bucketName, S3Object object, PutObjectOptions... options);
/**
* Create and name your own bucket in which to store your objects.
@ -239,11 +180,7 @@ public interface S3Client {
* />
*
*/
@PUT
@Path("/")
@ExceptionParser(ReturnTrueIfBucketAlreadyOwnedByYou.class)
Future<Boolean> putBucketIfNotExists(@HostPrefixParam String bucketName,
PutBucketOptions... options);
boolean putBucketIfNotExists(String bucketName, PutBucketOptions... options);
/**
* Deletes the bucket, if it is empty.
@ -262,22 +199,15 @@ public interface S3Client {
* "http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketDELETE.html"
* />
*/
@DELETE
@Path("/")
@ExceptionParser(ReturnTrueOn404FalseIfNotEmpty.class)
Future<Boolean> deleteBucketIfEmpty(@HostPrefixParam String bucketName);
boolean deleteBucketIfEmpty(String bucketName);
/**
* Issues a HEAD command to determine if the bucket exists or not.
*/
@HEAD
@Path("/")
@QueryParams(keys = "max-keys", values = "0")
@ExceptionParser(ReturnFalseOn404.class)
boolean bucketExists(@HostPrefixParam String bucketName);
boolean bucketExists(String bucketName);
/**
* Retrieve a <code>S3Bucket</code> listing. A GET request operation using a bucket URI lists
* Retrieve a <code>S3Bucket</code listing. A GET request operation using a bucket URI lists
* information about the objects in the bucket. You can use {@link ListBucketOptions} to control
* the amount of S3Objects to return.
* <p />
@ -294,11 +224,7 @@ public interface S3Client {
* href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html"
* />
*/
@GET
@Path("/")
@XMLResponseParser(ListBucketHandler.class)
Future<ListBucketResponse> listBucket(@HostPrefixParam String bucketName,
ListBucketOptions... options);
ListBucketResponse listBucket(String bucketName, ListBucketOptions... options);
/**
* Returns a list of all of the buckets owned by the authenticated sender of the request.
@ -309,10 +235,7 @@ public interface S3Client {
* />
*
*/
@GET
@XMLResponseParser(ListAllMyBucketsHandler.class)
@Path("/")
Future<? extends SortedSet<BucketMetadata>> listOwnedBuckets();
SortedSet<BucketMetadata> listOwnedBuckets();
/**
* Copies one object to another bucket, retaining UserMetadata from the source. The destination
@ -336,14 +259,8 @@ public interface S3Client {
* @see CopyObjectOptions
* @see org.jclouds.aws.s3.domain.CannedAccessPolicy
*/
@PUT
@Path("{destinationObject}")
@Headers(keys = "x-amz-copy-source", values = "/{sourceBucket}/{sourceObject}")
@XMLResponseParser(CopyObjectHandler.class)
Future<ObjectMetadata> copyObject(@PathParam("sourceBucket") String sourceBucket,
@PathParam("sourceObject") String sourceObject,
@HostPrefixParam String destinationBucket,
@PathParam("destinationObject") String destinationObject, CopyObjectOptions... options);
ObjectMetadata copyObject(String sourceBucket, String sourceObject, String destinationBucket,
String destinationObject, CopyObjectOptions... options);
/**
*
@ -356,12 +273,7 @@ public interface S3Client {
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html"/>
*/
@GET
@QueryParams(keys = "acl")
@XMLResponseParser(AccessControlListHandler.class)
@ExceptionParser(ThrowContainerNotFoundOn404.class)
@Path("/")
Future<AccessControlList> getBucketACL(@HostPrefixParam String bucketName);
AccessControlList getBucketACL(String bucketName);
/**
* Update a bucket's Access Control List settings.
@ -374,17 +286,13 @@ public interface S3Client {
* @param bucketName
* the bucket whose Access Control List settings will be updated.
* @param acl
* the ACL to apply to the bucket. This acl object <strong>must</strong> include a
* valid owner identifier string in {@link AccessControlList#getOwner()}.
* the ACL to apply to the bucket. This acl object <strong>must</strong include a valid
* owner identifier string in {@link AccessControlList#getOwner()}.
* @return true if the bucket's Access Control List was updated successfully.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html"/>
*/
@PUT
@Path("/")
@QueryParams(keys = "acl")
Future<Boolean> putBucketACL(@HostPrefixParam String bucketName,
@BinderParam(BindACLToXMLEntity.class) AccessControlList acl);
boolean putBucketACL(String bucketName, AccessControlList acl);
/**
* A GET request operation directed at an object or bucket URI with the "acl" parameter retrieves
@ -396,13 +304,7 @@ public interface S3Client {
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html"/>
*/
@GET
@QueryParams(keys = "acl")
@Path("{key}")
@XMLResponseParser(AccessControlListHandler.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
Future<AccessControlList> getObjectACL(@HostPrefixParam String bucketName,
@PathParam("key") String key);
AccessControlList getObjectACL(String bucketName, String key);
/**
* Update an object's Access Control List settings.
@ -417,16 +319,12 @@ public interface S3Client {
* @param objectKey
* the key of the object whose Access Control List settings will be updated.
* @param acl
* the ACL to apply to the object. This acl object <strong>must</strong> include a
* valid owner identifier string in {@link AccessControlList#getOwner()}.
* the ACL to apply to the object. This acl object <strong>must</strong include a valid
* owner identifier string in {@link AccessControlList#getOwner()}.
* @return true if the object's Access Control List was updated successfully.
*
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html"/>
*/
@PUT
@QueryParams(keys = "acl")
@Path("{key}")
Future<Boolean> putObjectACL(@HostPrefixParam String bucketName, @PathParam("key") String key,
@BinderParam(BindACLToXMLEntity.class) AccessControlList acl);
boolean putObjectACL(String bucketName, String key, AccessControlList acl);
}

View File

@ -50,11 +50,11 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole, Andrew Newdigate
* @see S3Context
*/
public class S3ContextBuilder extends RestContextBuilder<S3Client> {
public class S3ContextBuilder extends RestContextBuilder<S3AsyncClient, S3Client> {
public S3ContextBuilder(Properties props) {
super(new TypeLiteral<S3Client>() {
super(new TypeLiteral<S3AsyncClient>() {
}, new TypeLiteral<S3Client>() {
}, props);
}
@ -67,7 +67,7 @@ public class S3ContextBuilder extends RestContextBuilder<S3Client> {
protected void addClientModule(List<Module> modules) {
modules.add(new S3RestClientModule());
}
@Override
public S3ContextBuilder withExecutorService(ExecutorService service) {
return (S3ContextBuilder) super.withExecutorService(service);

View File

@ -42,22 +42,23 @@ import com.google.inject.Module;
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see S3Client
* @see S3AsyncClient
*/
public class S3ContextFactory {
public static RestContext<S3Client> createContext(Properties properties, Module... modules) {
public static RestContext<S3AsyncClient, S3Client> createContext(Properties properties,
Module... modules) {
return new S3ContextBuilder(new S3PropertiesBuilder(properties).build()).withModules(modules)
.buildContext();
}
public static RestContext<S3Client> createContext(String awsAccessKeyId,
public static RestContext<S3AsyncClient, S3Client> createContext(String awsAccessKeyId,
String awsSecretAccessKey, Module... modules) {
return new S3ContextBuilder(new S3PropertiesBuilder(awsAccessKeyId, awsSecretAccessKey)
.build()).withModules(modules).buildContext();
}
public static RestContext<S3Client> createContext(URI endpoint, String awsAccessKeyId,
public static RestContext<S3AsyncClient, S3Client> createContext(URI endpoint, String awsAccessKeyId,
String awsSecretAccessKey, Module... modules) {
return new S3ContextBuilder(new S3PropertiesBuilder(awsAccessKeyId, awsSecretAccessKey)
.withEndpoint(endpoint).build()).withModules(modules).buildContext();

View File

@ -0,0 +1,161 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.blobstore;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import java.util.SortedSet;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.inject.Inject;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
import org.jclouds.aws.s3.blobstore.functions.BlobToObjectGetOptions;
import org.jclouds.aws.s3.blobstore.functions.BucketToResourceList;
import org.jclouds.aws.s3.blobstore.functions.BucketToResourceMetadata;
import org.jclouds.aws.s3.blobstore.functions.ContainerToBucketListOptions;
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.aws.s3.blobstore.internal.BaseS3BlobStore;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.options.ListBucketOptions;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
public class S3AsyncBlobStore extends BaseS3BlobStore implements AsyncBlobStore {
@Inject
public S3AsyncBlobStore(S3AsyncClient async, S3Client sync, Factory blobFactory,
LoggerFactory logFactory, ClearListStrategy clearContainerStrategy,
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object,
ContainerToBucketListOptions container2BucketListOptions,
BlobToObjectGetOptions blob2ObjectGetOptions,
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
ExecutorService service) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2BucketListOptions, blob2ObjectGetOptions,
bucket2ResourceMd, bucket2ResourceList, service);
}
/**
* This implementation uses the S3 HEAD Object command to return the result
*/
public Future<BlobMetadata> blobMetadata(String container, String key) {
return wrapFuture(async.headObject(container, key),
new Function<ObjectMetadata, BlobMetadata>() {
@Override
public BlobMetadata apply(ObjectMetadata from) {
return object2BlobMd.apply(from);
}
});
}
public Future<Void> clearContainer(final String container) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
return null;
}
});
}
public Future<Boolean> createContainer(String container) {
return async.putBucketIfNotExists(container);
}
public Future<Void> deleteContainer(final String container) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
async.deleteBucketIfEmpty(container).get();
return null;
}
});
}
public Future<Boolean> exists(String container) {
return async.bucketExists(container);
}
public Future<Blob> getBlob(String container, String key,
org.jclouds.blobstore.options.GetOptions... optionsList) {
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
Future<S3Object> returnVal = async.getObject(container, key, httpOptions);
return wrapFuture(returnVal, object2Blob);
}
public Future<? extends ListResponse<? extends ResourceMetadata>> list() {
return wrapFuture(
async.listOwnedBuckets(),
new Function<SortedSet<BucketMetadata>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
SortedSet<BucketMetadata> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
bucket2ResourceMd), null, null, false);
}
});
}
public Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(
String container, ListContainerOptions... optionsList) {
ListBucketOptions httpOptions = container2BucketListOptions.apply(optionsList);
Future<ListBucketResponse> returnVal = async.listBucket(container, httpOptions);
return wrapFuture(returnVal, bucket2ResourceList);
}
public Future<String> putBlob(String container, Blob blob) {
return async.putObject(container, blob2Object.apply(blob));
}
public Future<Void> removeBlob(String container, String key) {
return async.deleteObject(container, key);
}
}

View File

@ -23,16 +23,14 @@
*/
package org.jclouds.aws.s3.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import java.util.SortedSet;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.inject.Inject;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
import org.jclouds.aws.s3.blobstore.functions.BlobToObjectGetOptions;
@ -41,145 +39,92 @@ import org.jclouds.aws.s3.blobstore.functions.BucketToResourceMetadata;
import org.jclouds.aws.s3.blobstore.functions.ContainerToBucketListOptions;
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.aws.s3.blobstore.internal.BaseS3BlobStore;
import org.jclouds.aws.s3.domain.BucketMetadata;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.options.ListBucketOptions;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.attr.ConsistencyModels;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
@ConsistencyModel(ConsistencyModels.EVENTUAL)
public class S3BlobStore implements BlobStore {
private final S3Client connection;
private final Blob.Factory blobFactory;
private final LoggerFactory logFactory;
private final ClearListStrategy clearContainerStrategy;
private final ObjectToBlobMetadata object2BlobMd;
private final ObjectToBlob object2Blob;
private final BlobToObject blob2Object;
private final ContainerToBucketListOptions container2BucketListOptions;
private final BlobToObjectGetOptions blob2ObjectGetOptions;
private final BucketToResourceMetadata bucket2ResourceMd;
private final BucketToResourceList bucket2ResourceList;
private final ExecutorService service;
public class S3BlobStore extends BaseS3BlobStore implements BlobStore {
@Inject
private S3BlobStore(S3Client connection, Blob.Factory blobFactory, LoggerFactory logFactory,
ClearListStrategy clearContainerStrategy, ObjectToBlobMetadata object2BlobMd,
ObjectToBlob object2Blob, BlobToObject blob2Object,
public S3BlobStore(S3AsyncClient async, S3Client sync, Factory blobFactory,
LoggerFactory logFactory, ClearListStrategy clearContainerStrategy,
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object,
ContainerToBucketListOptions container2BucketListOptions,
BlobToObjectGetOptions blob2ObjectGetOptions,
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
ExecutorService service) {
this.connection = checkNotNull(connection, "connection");
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
this.logFactory = checkNotNull(logFactory, "logFactory");
this.clearContainerStrategy = checkNotNull(clearContainerStrategy, "clearContainerStrategy");
this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd");
this.object2Blob = checkNotNull(object2Blob, "object2Blob");
this.blob2Object = checkNotNull(blob2Object, "blob2Object");
this.container2BucketListOptions = checkNotNull(container2BucketListOptions,
"container2BucketListOptions");
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
this.bucket2ResourceMd = checkNotNull(bucket2ResourceMd, "bucket2ResourceMd");
this.bucket2ResourceList = checkNotNull(bucket2ResourceList, "bucket2ResourceList");
this.service = checkNotNull(service, "service");
}
protected <F, T> Future<T> wrapFuture(Future<? extends F> future, Function<F, T> function) {
return new FutureFunctionWrapper<F, T>(future, function, logFactory.getLogger(function
.getClass().getName()));
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2BucketListOptions, blob2ObjectGetOptions,
bucket2ResourceMd, bucket2ResourceList, service);
}
/**
* This implementation uses the S3 HEAD Object command to return the result
*/
public BlobMetadata blobMetadata(String container, String key) {
return object2BlobMd.apply(connection.headObject(container, key));
return object2BlobMd.apply(sync.headObject(container, key));
}
public Future<Void> clearContainer(final String container) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
return null;
}
});
public void clearContainer(String container) {
clearContainerStrategy.execute(container, recursive());
}
public Future<Boolean> createContainer(String container) {
return connection.putBucketIfNotExists(container);
public boolean createContainer(String container) {
return sync.putBucketIfNotExists(container);
}
public Future<Void> deleteContainer(final String container) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
connection.deleteBucketIfEmpty(container).get();
return null;
}
});
public void deleteContainer(String container) {
clearContainer(container);
sync.deleteBucketIfEmpty(container);
}
public boolean exists(String container) {
return connection.bucketExists(container);
return sync.bucketExists(container);
}
public Future<Blob> getBlob(String container, String key,
public Blob getBlob(String container, String key,
org.jclouds.blobstore.options.GetOptions... optionsList) {
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
Future<S3Object> returnVal = connection.getObject(container, key, httpOptions);
return wrapFuture(returnVal, object2Blob);
return object2Blob.apply(sync.getObject(container, key, httpOptions));
}
public Future<? extends ListResponse<? extends ResourceMetadata>> list() {
return wrapFuture(
connection.listOwnedBuckets(),
new Function<SortedSet<BucketMetadata>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
SortedSet<BucketMetadata> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
bucket2ResourceMd), null, null, false);
}
});
public ListResponse<? extends ResourceMetadata> list() {
return new Function<SortedSet<BucketMetadata>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
SortedSet<BucketMetadata> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
bucket2ResourceMd), null, null, false);
}
}.apply(sync.listOwnedBuckets());
}
public Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(String container,
public ListContainerResponse<? extends ResourceMetadata> list(String container,
ListContainerOptions... optionsList) {
ListBucketOptions httpOptions = container2BucketListOptions.apply(optionsList);
Future<ListBucketResponse> returnVal = connection.listBucket(container, httpOptions);
return wrapFuture(returnVal, bucket2ResourceList);
return bucket2ResourceList.apply(sync.listBucket(container, httpOptions));
}
public Future<String> putBlob(String container, Blob blob) {
return connection.putObject(container, blob2Object.apply(blob));
public String putBlob(String container, Blob blob) {
return sync.putObject(container, blob2Object.apply(blob));
}
public Future<Void> removeBlob(String container, String key) {
return connection.deleteObject(container, key);
}
public Blob newBlob() {
return blobFactory.create(null);
public void removeBlob(String container, String key) {
sync.deleteObject(container, key);
}
}

View File

@ -23,13 +23,18 @@
*/
package org.jclouds.aws.s3.blobstore;
import static org.jclouds.aws.s3.reference.S3Constants.*;
import static org.jclouds.blobstore.reference.BlobStoreConstants.*;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_METADATA_PREFIX;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_RETRY;
import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_TIMEOUT;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_RETRY;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
import java.util.List;
import java.util.Properties;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.config.S3BlobStoreContextModule;
import org.jclouds.aws.s3.config.S3RestClientModule;
@ -55,10 +60,11 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole, Andrew Newdigate
* @see S3BlobStoreContext
*/
public class S3BlobStoreContextBuilder extends BlobStoreContextBuilder<S3Client> {
public class S3BlobStoreContextBuilder extends BlobStoreContextBuilder<S3AsyncClient, S3Client> {
public S3BlobStoreContextBuilder(Properties props) {
super(new TypeLiteral<S3Client>() {
super(new TypeLiteral<S3AsyncClient>() {
}, new TypeLiteral<S3Client>() {
}, convert(props));
}

View File

@ -26,6 +26,7 @@ package org.jclouds.aws.s3.blobstore;
import java.net.URI;
import java.util.Properties;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.S3PropertiesBuilder;
import org.jclouds.blobstore.BlobStoreContext;
@ -47,18 +48,18 @@ import com.google.inject.Module;
* @see S3BlobStoreContext
*/
public class S3BlobStoreContextFactory {
public static BlobStoreContext<S3Client> createContext(Properties properties, Module... modules) {
public static BlobStoreContext<S3AsyncClient, S3Client> createContext(Properties properties, Module... modules) {
return new S3BlobStoreContextBuilder(new S3PropertiesBuilder(properties).build())
.withModules(modules).buildContext();
}
public static BlobStoreContext<S3Client> createContext(String awsAccessKeyId,
public static BlobStoreContext<S3AsyncClient, S3Client> createContext(String awsAccessKeyId,
String awsSecretAccessKey, Module... modules) {
return new S3BlobStoreContextBuilder(new S3PropertiesBuilder(awsAccessKeyId,
awsSecretAccessKey).build()).withModules(modules).buildContext();
}
public static BlobStoreContext<S3Client> createContext(URI endpoint, String awsAccessKeyId,
public static BlobStoreContext<S3AsyncClient, S3Client> createContext(URI endpoint, String awsAccessKeyId,
String awsSecretAccessKey, Module... modules) {
return new S3BlobStoreContextBuilder(new S3PropertiesBuilder(awsAccessKeyId,
awsSecretAccessKey).withEndpoint(endpoint).build()).withModules(modules)

View File

@ -30,9 +30,12 @@ import javax.inject.Singleton;
import org.jclouds.aws.reference.AWSConstants;
import org.jclouds.aws.s3.S3;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.S3AsyncBlobStore;
import org.jclouds.aws.s3.blobstore.S3BlobStore;
import org.jclouds.aws.s3.config.S3ObjectModule;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobMap;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
@ -46,7 +49,7 @@ import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* Configures the {@link S3BlobStoreContext}; requires {@link S3BlobStore} bound.
* Configures the {@link S3BlobStoreContext}; requires {@link S3AsyncBlobStore} bound.
*
* @author Adrian Cole
*/
@ -57,17 +60,20 @@ public class S3BlobStoreContextModule extends AbstractModule {
install(new BlobStoreObjectModule());
install(new BlobStoreMapModule());
install(new S3ObjectModule());
bind(AsyncBlobStore.class).to(S3AsyncBlobStore.class).asEagerSingleton();
bind(BlobStore.class).to(S3BlobStore.class).asEagerSingleton();
}
@Provides
@Singleton
BlobStoreContext<S3Client> provideContext(BlobMap.Factory blobMapFactory,
InputStreamMap.Factory inputStreamMapFactory, Closer closer, BlobStore blobStore,
BlobStoreContext<S3AsyncClient, S3Client> provideContext(BlobMap.Factory blobMapFactory,
InputStreamMap.Factory inputStreamMapFactory, Closer closer,
AsyncBlobStore asyncBlobstore, BlobStore blobStore, S3AsyncClient asynchApi,
S3Client defaultApi, @S3 URI endPoint,
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
return new BlobStoreContextImpl<S3Client>(blobMapFactory, inputStreamMapFactory, closer,
blobStore, defaultApi, endPoint, account);
return new BlobStoreContextImpl<S3AsyncClient, S3Client>(blobMapFactory,
inputStreamMapFactory, closer, asyncBlobstore, blobStore, asynchApi, defaultApi,
endPoint, account);
}
}

View File

@ -0,0 +1,97 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.s3.blobstore.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.inject.Inject;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
import org.jclouds.aws.s3.blobstore.functions.BlobToObjectGetOptions;
import org.jclouds.aws.s3.blobstore.functions.BucketToResourceList;
import org.jclouds.aws.s3.blobstore.functions.BucketToResourceMetadata;
import org.jclouds.aws.s3.blobstore.functions.ContainerToBucketListOptions;
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlob;
import org.jclouds.aws.s3.blobstore.functions.ObjectToBlobMetadata;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.logging.Logger.LoggerFactory;
import com.google.common.base.Function;
public class BaseS3BlobStore {
protected final S3AsyncClient async;
protected final S3Client sync;
protected final Blob.Factory blobFactory;
protected final LoggerFactory logFactory;
protected final ClearListStrategy clearContainerStrategy;
protected final ObjectToBlobMetadata object2BlobMd;
protected final ObjectToBlob object2Blob;
protected final BlobToObject blob2Object;
protected final ContainerToBucketListOptions container2BucketListOptions;
protected final BlobToObjectGetOptions blob2ObjectGetOptions;
protected final BucketToResourceMetadata bucket2ResourceMd;
protected final BucketToResourceList bucket2ResourceList;
protected final ExecutorService service;
@Inject
protected BaseS3BlobStore(S3AsyncClient async, S3Client sync, Blob.Factory blobFactory,
LoggerFactory logFactory, ClearListStrategy clearContainerStrategy,
ObjectToBlobMetadata object2BlobMd, ObjectToBlob object2Blob, BlobToObject blob2Object,
ContainerToBucketListOptions container2BucketListOptions,
BlobToObjectGetOptions blob2ObjectGetOptions,
BucketToResourceMetadata bucket2ResourceMd, BucketToResourceList bucket2ResourceList,
ExecutorService service) {
this.async = checkNotNull(async, "async");
this.sync = checkNotNull(sync, "sync");
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
this.logFactory = checkNotNull(logFactory, "logFactory");
this.clearContainerStrategy = checkNotNull(clearContainerStrategy, "clearContainerStrategy");
this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd");
this.object2Blob = checkNotNull(object2Blob, "object2Blob");
this.blob2Object = checkNotNull(blob2Object, "blob2Object");
this.container2BucketListOptions = checkNotNull(container2BucketListOptions,
"container2BucketListOptions");
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
this.bucket2ResourceMd = checkNotNull(bucket2ResourceMd, "bucket2ResourceMd");
this.bucket2ResourceList = checkNotNull(bucket2ResourceList, "bucket2ResourceList");
this.service = checkNotNull(service, "service");
}
protected <F, T> Future<T> wrapFuture(Future<? extends F> future, Function<F, T> function) {
return new FutureFunctionWrapper<F, T>(future, function, logFactory.getLogger(function
.getClass().getName()));
}
public Blob newBlob() {
return blobFactory.create(null);
}
}

View File

@ -30,6 +30,7 @@ import javax.inject.Singleton;
import org.jclouds.aws.reference.AWSConstants;
import org.jclouds.aws.s3.S3;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.blobstore.config.BlobStoreObjectModule;
import org.jclouds.lifecycle.Closer;
@ -40,7 +41,7 @@ import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* Configures the {@link S3ContextModule}; requires {@link S3Client} bound.
* Configures the {@link S3ContextModule}; requires {@link S3AsyncClient} bound.
*
* @author Adrian Cole
*/
@ -55,9 +56,11 @@ public class S3ContextModule extends AbstractModule {
@Provides
@Singleton
RestContext<S3Client> provideContext(Closer closer, S3Client defaultApi, @S3 URI endPoint,
RestContext<S3AsyncClient, S3Client> provideContext(Closer closer, S3AsyncClient defaultApi,
S3Client syncApi, @S3 URI endPoint,
@Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
return new RestContextImpl<S3Client>(closer, defaultApi, endPoint, account);
return new RestContextImpl<S3AsyncClient, S3Client>(closer, defaultApi, syncApi, endPoint,
account);
}
}

View File

@ -33,11 +33,13 @@ import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
import org.jclouds.aws.handlers.ParseAWSErrorFromXmlContent;
import org.jclouds.aws.s3.S3;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.filters.RequestAuthorizeSignature;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.aws.util.RequestSigner;
import org.jclouds.concurrent.ExpirableSupplier;
import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
@ -68,13 +70,12 @@ public class S3RestClientModule extends AbstractModule {
protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
return cache.get();
}
@Provides
@Singleton
RequestSigner provideRequestSigner(RequestAuthorizeSignature in){
RequestSigner provideRequestSigner(RequestAuthorizeSignature in) {
return in;
}
/**
* borrowing concurrency code to ensure that caching takes place properly
@ -107,8 +108,15 @@ public class S3RestClientModule extends AbstractModule {
@Provides
@Singleton
protected S3Client provideS3Client(RestClientFactory factory) {
return factory.create(S3Client.class);
protected S3AsyncClient provideAsyncClient(RestClientFactory factory) {
return factory.create(S3AsyncClient.class);
}
@Provides
@Singleton
public S3Client provideClient(S3AsyncClient client) throws IllegalArgumentException,
SecurityException, NoSuchMethodException {
return SyncProxy.create(S3Client.class, client);
}
protected void bindErrorHandlers() {

View File

@ -48,7 +48,7 @@ public class CanonicalUser {
/**
* To locate the CanonicalUser ID for a user, the user must perform the
* {@link org.jclouds.aws.s3.blobstore.S3BlobStore#list(String)} and retrieve
* {@link org.jclouds.aws.s3.blobstore.S3AsyncBlobStore#list(String)} and retrieve
* {@link BucketMetadata#getOwner()}
*/
public String getId() {

View File

@ -31,7 +31,6 @@ import static org.testng.Assert.assertNotNull;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.ec2.domain.Image;
@ -63,7 +62,7 @@ public class EC2ClientLiveTest {
private String imageId = "ami-d7fe1fbe";
@BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
public void setupClient() {
user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
@ -71,15 +70,14 @@ public class EC2ClientLiveTest {
}
@Test
void testDescribeImages() throws InterruptedException, ExecutionException, TimeoutException {
SortedSet<Image> allResults = client.describeImages().get(120, TimeUnit.SECONDS);
void testDescribeImages() {
SortedSet<Image> allResults = client.describeImages();
assertNotNull(allResults);
assert allResults.size() >= 2 : allResults.size();
Iterator<Image> iterator = allResults.iterator();
String id1 = iterator.next().getImageId();
String id2 = iterator.next().getImageId();
SortedSet<Image> twoResults = client.describeImages(imageIds(id1, id2)).get(30,
TimeUnit.SECONDS);
SortedSet<Image> twoResults = client.describeImages(imageIds(id1, id2));
assertNotNull(twoResults);
assertEquals(twoResults.size(), 2);
iterator = twoResults.iterator();
@ -88,14 +86,12 @@ public class EC2ClientLiveTest {
}
@Test
void testDescribeAddresses() throws InterruptedException, ExecutionException, TimeoutException {
SortedSet<PublicIpInstanceIdPair> allResults = client.describeAddresses().get(30,
TimeUnit.SECONDS);
void testDescribeAddresses() {
SortedSet<PublicIpInstanceIdPair> allResults = client.describeAddresses();
assertNotNull(allResults);
if (allResults.size() >= 1) {
PublicIpInstanceIdPair pair = allResults.last();
SortedSet<PublicIpInstanceIdPair> result = client.describeAddresses(pair.getPublicIp())
.get(30, TimeUnit.SECONDS);
SortedSet<PublicIpInstanceIdPair> result = client.describeAddresses(pair.getPublicIp());
assertNotNull(result);
PublicIpInstanceIdPair compare = result.last();
assertEquals(compare, pair);
@ -105,8 +101,7 @@ public class EC2ClientLiveTest {
@Test(dependsOnMethods = "testDescribeImages", enabled = false)
void testDescribeImageAttribute() throws InterruptedException, ExecutionException,
TimeoutException {
SortedSet<Image> oneResult = client.describeImages(imageIds(imageId)).get(30,
TimeUnit.SECONDS);
SortedSet<Image> oneResult = client.describeImages(imageIds(imageId));
@SuppressWarnings("unused")
Image expects = oneResult.last();
@ -122,16 +117,15 @@ public class EC2ClientLiveTest {
}
@Test
void testDescribeInstances() throws InterruptedException, ExecutionException, TimeoutException {
SortedSet<Reservation> allResults = client.describeInstances().get(30, TimeUnit.SECONDS);
void testDescribeInstances() {
SortedSet<Reservation> allResults = client.describeInstances();
assertNotNull(allResults);
assert allResults.size() >= 0 : allResults.size();
if (allResults.size() >= 2) {
Iterator<Reservation> iterator = allResults.iterator();
String id1 = iterator.next().getRunningInstances().first().getInstanceId();
String id2 = iterator.next().getRunningInstances().first().getInstanceId();
SortedSet<Reservation> twoResults = client.describeInstances(id1, id2).get(30,
TimeUnit.SECONDS);
SortedSet<Reservation> twoResults = client.describeInstances(id1, id2);
assertNotNull(twoResults);
assertEquals(twoResults.size(), 2);
iterator = allResults.iterator();
@ -141,16 +135,15 @@ public class EC2ClientLiveTest {
}
@Test
void testDescribeKeyPairs() throws InterruptedException, ExecutionException, TimeoutException {
SortedSet<KeyPair> allResults = client.describeKeyPairs().get(30, TimeUnit.SECONDS);
void testDescribeKeyPairs() {
SortedSet<KeyPair> allResults = client.describeKeyPairs();
assertNotNull(allResults);
assert allResults.size() >= 0 : allResults.size();
if (allResults.size() >= 2) {
Iterator<KeyPair> iterator = allResults.iterator();
String id1 = iterator.next().getKeyName();
String id2 = iterator.next().getKeyName();
SortedSet<KeyPair> twoResults = client.describeKeyPairs(id1, id2)
.get(30, TimeUnit.SECONDS);
SortedSet<KeyPair> twoResults = client.describeKeyPairs(id1, id2);
assertNotNull(twoResults);
assertEquals(twoResults.size(), 2);
iterator = twoResults.iterator();
@ -162,16 +155,14 @@ public class EC2ClientLiveTest {
@Test
void testDescribeSecurityGroups() throws InterruptedException, ExecutionException,
TimeoutException {
SortedSet<SecurityGroup> allResults = client.describeSecurityGroups().get(30,
TimeUnit.SECONDS);
SortedSet<SecurityGroup> allResults = client.describeSecurityGroups();
assertNotNull(allResults);
assert allResults.size() >= 0 : allResults.size();
if (allResults.size() >= 2) {
Iterator<SecurityGroup> iterator = allResults.iterator();
String id1 = iterator.next().getName();
String id2 = iterator.next().getName();
SortedSet<SecurityGroup> twoResults = client.describeSecurityGroups(id1, id2).get(30,
TimeUnit.SECONDS);
SortedSet<SecurityGroup> twoResults = client.describeSecurityGroups(id1, id2);
assertNotNull(twoResults);
assertEquals(twoResults.size(), 2);
iterator = twoResults.iterator();
@ -183,22 +174,22 @@ public class EC2ClientLiveTest {
public static final String PREFIX = System.getProperty("user.name") + "-ec2";
@Test
void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException {
void testCreateKeyPair() {
String keyName = PREFIX + "1";
try {
client.deleteKeyPair(keyName).get(30, TimeUnit.SECONDS);
client.deleteKeyPair(keyName);
} catch (Exception e) {
}
client.deleteKeyPair(keyName).get(30, TimeUnit.SECONDS);
client.deleteKeyPair(keyName);
KeyPair result = client.createKeyPair(keyName).get(30, TimeUnit.SECONDS);
KeyPair result = client.createKeyPair(keyName);
assertNotNull(result);
assertNotNull(result.getKeyMaterial());
assertNotNull(result.getKeyFingerprint());
assertEquals(result.getKeyName(), keyName);
SortedSet<KeyPair> twoResults = client.describeKeyPairs(keyName).get(30, TimeUnit.SECONDS);
SortedSet<KeyPair> twoResults = client.describeKeyPairs(keyName);
assertNotNull(twoResults);
assertEquals(twoResults.size(), 1);
KeyPair listPair = twoResults.iterator().next();
@ -207,17 +198,17 @@ public class EC2ClientLiveTest {
}
@Test
void testCreateSecurityGroup() throws InterruptedException, ExecutionException, TimeoutException {
void testCreateSecurityGroup() {
String groupName = PREFIX + "1";
String groupDescription = PREFIX + "1 description";
try {
client.deleteSecurityGroup(groupName).get(30, TimeUnit.SECONDS);
client.deleteSecurityGroup(groupName);
} catch (Exception e) {
}
client.deleteSecurityGroup(groupName).get(30, TimeUnit.SECONDS);
client.deleteSecurityGroup(groupName);
client.createSecurityGroup(groupName, groupDescription).get(30, TimeUnit.SECONDS);
client.createSecurityGroup(groupName, groupDescription);
verifySecurityGroup(groupName, groupDescription);
}
@ -228,26 +219,22 @@ public class EC2ClientLiveTest {
String groupName = PREFIX + "ingress";
try {
client.deleteSecurityGroup(groupName).get(30, TimeUnit.SECONDS);
client.deleteSecurityGroup(groupName);
} catch (Exception e) {
}
client.createSecurityGroup(groupName, groupName).get(30, TimeUnit.SECONDS);
client.authorizeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0").get(30,
TimeUnit.SECONDS);
client.createSecurityGroup(groupName, groupName);
client.authorizeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
assertEventually(new GroupHasPermission(client, groupName, new IpPermission(80, 80, Sets
.<UserIdGroupPair> newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0"))));
client.revokeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0").get(30,
TimeUnit.SECONDS);
client.revokeSecurityGroupIngress(groupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
assertEventually(new GroupHasNoPermissions(client, groupName));
}
private void verifySecurityGroup(String groupName, String description)
throws InterruptedException, ExecutionException, TimeoutException {
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(groupName).get(30,
TimeUnit.SECONDS);
private void verifySecurityGroup(String groupName, String description) {
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(groupName);
assertNotNull(oneResult);
assertEquals(oneResult.size(), 1);
SecurityGroup listPair = oneResult.iterator().next();
@ -257,44 +244,41 @@ public class EC2ClientLiveTest {
@Test(enabled = false)
// TODO
void testAuthorizeSecurityGroupIngressSourceGroup() throws InterruptedException,
ExecutionException, TimeoutException {
void testAuthorizeSecurityGroupIngressSourceGroup() throws InterruptedException {
String group1Name = PREFIX + "ingress1";
String group2Name = PREFIX + "ingress2";
try {
client.deleteSecurityGroup(group1Name).get(30, TimeUnit.SECONDS);
client.deleteSecurityGroup(group1Name);
} catch (Exception e) {
}
try {
client.deleteSecurityGroup(group2Name).get(30, TimeUnit.SECONDS);
client.deleteSecurityGroup(group2Name);
} catch (Exception e) {
}
client.createSecurityGroup(group1Name, group1Name).get(30, TimeUnit.SECONDS);
client.createSecurityGroup(group2Name, group2Name).get(30, TimeUnit.SECONDS);
client.createSecurityGroup(group1Name, group1Name);
client.createSecurityGroup(group2Name, group2Name);
ensureGroupsExist(group1Name, group2Name);
client.authorizeSecurityGroupIngress(group1Name, IpProtocol.TCP, 80, 80, "0.0.0.0/0").get(30,
TimeUnit.SECONDS);
client.authorizeSecurityGroupIngress(group1Name, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets
.<UserIdGroupPair> newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0"))));
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(group1Name).get(30,
TimeUnit.SECONDS);
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(group1Name);
assertNotNull(oneResult);
assertEquals(oneResult.size(), 1);
SecurityGroup group = oneResult.iterator().next();
assertEquals(group.getName(), group1Name);
client.authorizeSecurityGroupIngress(group2Name,
new UserIdGroupPair(group.getOwnerId(), group1Name)).get(30, TimeUnit.SECONDS);
client.authorizeSecurityGroupIngress(group2Name, new UserIdGroupPair(group.getOwnerId(),
group1Name));
assertEventually(new GroupHasPermission(client, group2Name, new IpPermission(80, 80, Sets
.<UserIdGroupPair> newTreeSet(), IpProtocol.TCP, ImmutableSortedSet.of("0.0.0.0/0"))));
client.revokeSecurityGroupIngress(group2Name,
new UserIdGroupPair(group.getOwnerId(), group1Name)).get(30, TimeUnit.SECONDS);
client.revokeSecurityGroupIngress(group2Name, new UserIdGroupPair(group.getOwnerId(),
group1Name));
assertEventually(new GroupHasNoPermissions(client, group2Name));
}
@ -311,8 +295,7 @@ public class EC2ClientLiveTest {
public void run() {
try {
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(group).get(30,
TimeUnit.SECONDS);
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(group);
assertNotNull(oneResult);
assertEquals(oneResult.size(), 1);
SecurityGroup listPair = oneResult.iterator().next();
@ -334,8 +317,7 @@ public class EC2ClientLiveTest {
public void run() {
try {
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(group).get(30,
TimeUnit.SECONDS);
SortedSet<SecurityGroup> oneResult = client.describeSecurityGroups(group);
assertNotNull(oneResult);
assertEquals(oneResult.size(), 1);
SecurityGroup listPair = oneResult.iterator().next();
@ -346,10 +328,8 @@ public class EC2ClientLiveTest {
}
}
private void ensureGroupsExist(String group1Name, String group2Name)
throws InterruptedException, ExecutionException, TimeoutException {
SortedSet<SecurityGroup> twoResults = client.describeSecurityGroups(group1Name, group2Name)
.get(30, TimeUnit.SECONDS);
private void ensureGroupsExist(String group1Name, String group2Name) {
SortedSet<SecurityGroup> twoResults = client.describeSecurityGroups(group1Name, group2Name);
assertNotNull(twoResults);
assertEquals(twoResults.size(), 2);
Iterator<SecurityGroup> iterator = twoResults.iterator();

View File

@ -73,12 +73,12 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.EC2ClientTest")
public class EC2ClientTest extends RestClientTest<EC2Client> {
public class EC2ClientTest extends RestClientTest<EC2AsyncClient> {
public void testDescribeImages() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("describeImages", Array.newInstance(
Method method = EC2AsyncClient.class.getMethod("describeImages", Array.newInstance(
DescribeImagesOptions.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method);
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -98,9 +98,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testDescribeImagesOptions() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("describeImages", Array.newInstance(
Method method = EC2AsyncClient.class.getMethod("describeImages", Array.newInstance(
DescribeImagesOptions.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, executableBy(
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, executableBy(
"me").ownedBy("fred", "nancy").imageIds("1", "2"));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -119,9 +119,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testDescribeImageAttribute() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("describeImageAttribute", String.class,
Method method = EC2AsyncClient.class.getMethod("describeImageAttribute", String.class,
ImageAttribute.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "imageId",
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "imageId",
ImageAttribute.BLOCK_DEVICE_MAPPING);
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -142,9 +142,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
public void testDescribeInstances() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("describeInstances", Array.newInstance(
Method method = EC2AsyncClient.class.getMethod("describeInstances", Array.newInstance(
String.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method);
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -160,9 +160,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testDescribeInstancesArgs() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("describeInstances", Array.newInstance(
Method method = EC2AsyncClient.class.getMethod("describeInstances", Array.newInstance(
String.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "1", "2");
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "1", "2");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -179,9 +179,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testTerminateInstances() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("terminateInstances", String.class, Array
Method method = EC2AsyncClient.class.getMethod("terminateInstances", String.class, Array
.newInstance(String.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "1", "2");
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "1", "2");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -197,9 +197,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
public void testRunInstances() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("runInstances", String.class, int.class, int.class,
Method method = EC2AsyncClient.class.getMethod("runInstances", String.class, int.class, int.class,
Array.newInstance(RunInstancesOptions.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "ami-voo", 1, 1);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "ami-voo", 1, 1);
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -216,9 +216,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testRunInstancesOptions() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("runInstances", String.class, int.class, int.class,
Method method = EC2AsyncClient.class.getMethod("runInstances", String.class, int.class, int.class,
Array.newInstance(RunInstancesOptions.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "ami-voo", 1, 5,
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "ami-voo", 1, 5,
new RunInstancesOptions().withKernelId("kernelId").enableMonitoring());
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -236,8 +236,8 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
public void testCreateKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("createKeyPair", String.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "mykey");
Method method = EC2AsyncClient.class.getMethod("createKeyPair", String.class);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "mykey");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -253,8 +253,8 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testDisassociateAddress() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("disassociateAddress", InetAddress.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, InetAddress
Method method = EC2AsyncClient.class.getMethod("disassociateAddress", InetAddress.class);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, InetAddress
.getByAddress(new byte[] { 127, 0, 0, 1 }));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -271,9 +271,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
public void testAssociateAddress() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class
Method method = EC2AsyncClient.class
.getMethod("associateAddress", InetAddress.class, String.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, InetAddress
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, InetAddress
.getByAddress(new byte[] { 127, 0, 0, 1 }), "me");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -290,8 +290,8 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
public void testReleaseAddress() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("releaseAddress", InetAddress.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, InetAddress
Method method = EC2AsyncClient.class.getMethod("releaseAddress", InetAddress.class);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, InetAddress
.getByAddress(new byte[] { 127, 0, 0, 1 }));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -307,9 +307,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
public void testDescribeAddresses() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("describeAddresses", Array.newInstance(
Method method = EC2AsyncClient.class.getMethod("describeAddresses", Array.newInstance(
InetAddress.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, InetAddress
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, InetAddress
.getByAddress(new byte[] { 127, 0, 0, 1 }));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -326,8 +326,8 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
public void testAllocateAddress() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("allocateAddress");
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method);
Method method = EC2AsyncClient.class.getMethod("allocateAddress");
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method);
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -342,8 +342,8 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
public void testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("deleteKeyPair", String.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "mykey");
Method method = EC2AsyncClient.class.getMethod("deleteKeyPair", String.class);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "mykey");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -358,9 +358,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
public void testDescribeKeyPairs() throws SecurityException, NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("describeKeyPairs", Array.newInstance(String.class,
Method method = EC2AsyncClient.class.getMethod("describeKeyPairs", Array.newInstance(String.class,
0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method);
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -376,9 +376,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testDescribeKeyPairsArgs() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("describeKeyPairs", Array.newInstance(String.class,
Method method = EC2AsyncClient.class.getMethod("describeKeyPairs", Array.newInstance(String.class,
0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "1", "2");
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "1", "2");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -395,8 +395,8 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testDeleteSecurityGroup() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("deleteSecurityGroup", String.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "name");
Method method = EC2AsyncClient.class.getMethod("deleteSecurityGroup", String.class);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "name");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -412,8 +412,8 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testCreateSecurityGroup() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("createSecurityGroup", String.class, String.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "name",
Method method = EC2AsyncClient.class.getMethod("createSecurityGroup", String.class, String.class);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "name",
"description");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -431,9 +431,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testDescribeSecurityGroups() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("describeSecurityGroups", Array.newInstance(
Method method = EC2AsyncClient.class.getMethod("describeSecurityGroups", Array.newInstance(
String.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method);
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method);
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -449,9 +449,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testDescribeSecurityGroupsArgs() throws SecurityException, NoSuchMethodException,
IOException {
Method method = EC2Client.class.getMethod("describeSecurityGroups", Array.newInstance(
Method method = EC2AsyncClient.class.getMethod("describeSecurityGroups", Array.newInstance(
String.class, 0).getClass());
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "1", "2");
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "1", "2");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
assertHeadersEqual(httpMethod,
@ -468,9 +468,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testAuthorizeSecurityGroupIngressGroup() throws SecurityException,
NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("authorizeSecurityGroupIngress", String.class,
Method method = EC2AsyncClient.class.getMethod("authorizeSecurityGroupIngress", String.class,
UserIdGroupPair.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "group",
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "group",
new UserIdGroupPair("sourceUser", "sourceGroup"));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -489,9 +489,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testAuthorizeSecurityGroupIngressCidr() throws SecurityException,
NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("authorizeSecurityGroupIngress", String.class,
Method method = EC2AsyncClient.class.getMethod("authorizeSecurityGroupIngress", String.class,
IpProtocol.class, int.class, int.class, String.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "group",
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "group",
IpProtocol.TCP, 6000, 7000, "0.0.0.0/0");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -510,9 +510,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testRevokeSecurityGroupIngressGroup() throws SecurityException,
NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("revokeSecurityGroupIngress", String.class,
Method method = EC2AsyncClient.class.getMethod("revokeSecurityGroupIngress", String.class,
UserIdGroupPair.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "group",
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "group",
new UserIdGroupPair("sourceUser", "sourceGroup"));
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -531,9 +531,9 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
public void testRevokeSecurityGroupIngressCidr() throws SecurityException,
NoSuchMethodException, IOException {
Method method = EC2Client.class.getMethod("revokeSecurityGroupIngress", String.class,
Method method = EC2AsyncClient.class.getMethod("revokeSecurityGroupIngress", String.class,
IpProtocol.class, int.class, int.class, String.class);
GeneratedHttpRequest<EC2Client> httpMethod = processor.createRequest(method, "group",
GeneratedHttpRequest<EC2AsyncClient> httpMethod = processor.createRequest(method, "group",
IpProtocol.TCP, 6000, 7000, "0.0.0.0/0");
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
@ -551,14 +551,14 @@ public class EC2ClientTest extends RestClientTest<EC2Client> {
}
@Override
protected void checkFilters(GeneratedHttpRequest<EC2Client> httpMethod) {
protected void checkFilters(GeneratedHttpRequest<EC2AsyncClient> httpMethod) {
assertEquals(httpMethod.getFilters().size(), 1);
assertEquals(httpMethod.getFilters().get(0).getClass(), FormSigner.class);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<EC2Client>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<EC2Client>>() {
protected TypeLiteral<RestAnnotationProcessor<EC2AsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<EC2AsyncClient>>() {
};
}

View File

@ -60,7 +60,7 @@ public class EC2ContextBuilderTest {
}
public void testBuildContext() {
RestContext<EC2Client> context = newBuilder().buildContext();
RestContext<EC2AsyncClient, EC2Client> context = newBuilder().buildContext();
assertEquals(context.getClass(), RestContextImpl.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("http://ec2.amazonaws.com"));
@ -68,7 +68,7 @@ public class EC2ContextBuilderTest {
public void testBuildInjector() {
Injector i = newBuilder().buildInjector();
assert i.getInstance(Key.get(new TypeLiteral<RestContext<EC2Client>>() {
assert i.getInstance(Key.get(new TypeLiteral<RestContext<EC2AsyncClient, EC2Client>>() {
})) != null; // TODO: test all things taken from context
assert i.getInstance(FormSigner.class) != null;
}

View File

@ -31,7 +31,6 @@ import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
@ -45,8 +44,6 @@ import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.PublicIpInstanceIdPair;
import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.concurrent.WithinThreadExecutorService;
import org.jclouds.concurrent.config.ExecutorServiceModule;
import org.jclouds.http.HttpResponseException;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
@ -59,7 +56,6 @@ import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
@ -86,13 +82,9 @@ public class ExpensiveEC2ClientLiveTest {
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
client = new EC2ContextBuilder(new EC2PropertiesBuilder(user, password).build()).withModules(
new Log4JLoggingModule()).buildContext().getApi();
Injector injector = Guice.createInjector(new Log4JLoggingModule(), new JschSshClientModule(),
new ExecutorServiceModule(new WithinThreadExecutorService()));
client = EC2ContextFactory.createContext(user, password, new Log4JLoggingModule()).getApi();
Injector injector = new EC2ContextBuilder(new EC2PropertiesBuilder(user, password).build())
.withModules(new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
client = injector.getInstance(EC2Client.class);
sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
@ -105,31 +97,29 @@ public class ExpensiveEC2ClientLiveTest {
securityGroupName = serverPrefix + "ingress";
try {
client.deleteSecurityGroup(securityGroupName).get(30, TimeUnit.SECONDS);
client.deleteSecurityGroup(securityGroupName);
} catch (Exception e) {
}
client.createSecurityGroup(securityGroupName, securityGroupName).get(30, TimeUnit.SECONDS);
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0")
.get(30, TimeUnit.SECONDS);
client.createSecurityGroup(securityGroupName, securityGroupName);
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
client
.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 443, 443,
"0.0.0.0/0").get(30, TimeUnit.SECONDS);
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0")
.get(30, TimeUnit.SECONDS);
"0.0.0.0/0");
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0");
}
@Test(enabled = true)
void testCreateKeyPair() throws InterruptedException, ExecutionException, TimeoutException {
String keyName = serverPrefix + "1";
try {
client.deleteKeyPair(keyName).get(30, TimeUnit.SECONDS);
client.deleteKeyPair(keyName);
} catch (Exception e) {
}
client.deleteKeyPair(keyName).get(30, TimeUnit.SECONDS);
client.deleteKeyPair(keyName);
keyPair = client.createKeyPair(keyName).get(30, TimeUnit.SECONDS);
keyPair = client.createKeyPair(keyName);
assertNotNull(keyPair);
assertNotNull(keyPair.getKeyMaterial());
assertNotNull(keyPair.getKeyFingerprint());
@ -143,18 +133,18 @@ public class ExpensiveEC2ClientLiveTest {
RunningInstance server = null;
while (server == null) {
try {
System.out.printf("%d: running instance%n", System.currentTimeMillis());
server = client.runInstances(
imageId,
1,
1,
withKeyName(keyPair.getKeyName()).asType(InstanceType.M1_SMALL)
.withSecurityGroup(securityGroupName)).get(30, TimeUnit.SECONDS)
.getRunningInstances().iterator().next();
} catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
.withSecurityGroup(securityGroupName)).getRunningInstances()
.iterator().next();
} catch (HttpResponseException htpe) {
if (htpe.getResponse().getStatusCode() == 400)
continue;
throw e;
throw htpe;
}
}
assertNotNull(server.getInstanceId());
@ -163,42 +153,43 @@ public class ExpensiveEC2ClientLiveTest {
server = blockUntilRunningInstanceActive(serverId);
sshPing(server);
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), serverId);
}
@Test(enabled = true, dependsOnMethods = "testCreateRunningInstance")
void testElasticIpAddress() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
address = client.allocateAddress().get(30, TimeUnit.SECONDS);
address = client.allocateAddress();
assertNotNull(address);
PublicIpInstanceIdPair compare = client.describeAddresses(address).get(30, TimeUnit.SECONDS)
.last();
PublicIpInstanceIdPair compare = client.describeAddresses(address).last();
assertEquals(compare.getPublicIp(), address);
assert compare.getInstanceId() == null;
client.associateAddress(address, serverId).get(30, TimeUnit.SECONDS);
client.associateAddress(address, serverId);
compare = client.describeAddresses(address).get(30, TimeUnit.SECONDS).last();
compare = client.describeAddresses(address).last();
assertEquals(compare.getPublicIp(), address);
assertEquals(compare.getInstanceId(), serverId);
Reservation reservation = client.describeInstances(serverId).get(30, TimeUnit.SECONDS).last();
Reservation reservation = client.describeInstances(serverId).last();
assertNotNull(reservation.getRunningInstances().last().getIpAddress());
assertFalse(reservation.getRunningInstances().last().getIpAddress().equals(address));
doCheckKey(address);
client.disassociateAddress(address).get(30, TimeUnit.SECONDS);
client.disassociateAddress(address);
compare = client.describeAddresses(address).get(30, TimeUnit.SECONDS).last();
compare = client.describeAddresses(address).last();
assertEquals(compare.getPublicIp(), address);
assert compare.getInstanceId() == null;
reservation = client.describeInstances(serverId).get(30, TimeUnit.SECONDS).last();
reservation = client.describeInstances(serverId).last();
// assert reservation.getRunningInstances().last().getIpAddress() == null; TODO
}
@ -242,28 +233,30 @@ public class ExpensiveEC2ClientLiveTest {
.getInstanceId(), currentDetails.getInstanceState());
Thread.sleep(5 * 1000);
}
System.out.printf("%s awaiting ssh service to start%n", currentDetails.getInstanceId());
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(),
currentDetails.getDnsName());
assert socketTester.apply(new InetSocketAddress(currentDetails.getDnsName(), 22));
System.out.printf("%s ssh service started%n", currentDetails.getInstanceId());
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), currentDetails
.getDnsName());
return currentDetails;
}
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (address != null)
client.releaseAddress(address).get(30, TimeUnit.SECONDS);
client.releaseAddress(address);
if (serverId != null)
client.terminateInstances(serverId).get(30, TimeUnit.SECONDS);
client.terminateInstances(serverId);
if (keyPair != null)
client.deleteKeyPair(keyPair.getKeyName()).get(30, TimeUnit.SECONDS);
client.deleteKeyPair(keyPair.getKeyName());
if (securityGroupName != null)
client.deleteSecurityGroup(securityGroupName).get(30, TimeUnit.SECONDS);
client.deleteSecurityGroup(securityGroupName);
}
private RunningInstance getRunningInstance(String serverId) throws InterruptedException,
ExecutionException, TimeoutException {
return client.describeInstances(serverId).get(15, TimeUnit.SECONDS).first()
.getRunningInstances().first();
return client.describeInstances(serverId).first().getRunningInstances().first();
}
}

View File

@ -25,6 +25,7 @@ package org.jclouds.aws.ec2.config;
import static org.testng.Assert.assertEquals;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.reference.EC2Constants;
import org.jclouds.concurrent.WithinThreadExecutorService;
@ -70,8 +71,8 @@ public class EC2ContextModuleTest {
@Test
void testContextImpl() {
RestContext<EC2Client> handler = createInjector().getInstance(
Key.get(new TypeLiteral<RestContext<EC2Client>>() {
RestContext<EC2AsyncClient, EC2Client> handler = createInjector().getInstance(
Key.get(new TypeLiteral<RestContext<EC2AsyncClient, EC2Client>>() {
}));
assertEquals(handler.getClass(), RestContextImpl.class);
}

View File

@ -23,8 +23,8 @@
*/
package org.jclouds.aws.s3;
import static org.jclouds.aws.s3.internal.StubS3Client.TEST_ACL_EMAIL;
import static org.jclouds.aws.s3.internal.StubS3Client.TEST_ACL_ID;
import static org.jclouds.aws.s3.internal.StubS3AsyncClient.TEST_ACL_EMAIL;
import static org.jclouds.aws.s3.internal.StubS3AsyncClient.TEST_ACL_ID;
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceETagDoesntMatch;
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceETagMatches;
import static org.jclouds.aws.s3.options.CopyObjectOptions.Builder.ifSourceModifiedSince;
@ -49,7 +49,6 @@ import java.net.URL;
import java.util.Map;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.s3.domain.AccessControlList;
@ -78,14 +77,14 @@ import com.google.common.collect.Maps;
* @author Adrian Cole
*/
@Test(groups = { "integration", "live" }, testName = "s3.S3ClientLiveTest")
public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient, S3Client> {
/**
* this method overrides containerName to ensure it isn't found
*/
@Test(groups = { "integration", "live" })
public void deleteContainerIfEmptyNotFound() throws Exception {
assert context.getApi().deleteBucketIfEmpty("dbienf").get(10, TimeUnit.SECONDS);
assert context.getApi().deleteBucketIfEmpty("dbienf");
}
@Test(groups = { "integration", "live" })
@ -93,7 +92,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
String containerName = getContainerName();
try {
addBlobToContainer(containerName, "test");
assert !context.getApi().deleteBucketIfEmpty(containerName).get(10, TimeUnit.SECONDS);
assert !context.getApi().deleteBucketIfEmpty(containerName);
} finally {
returnContainer(containerName);
}
@ -108,7 +107,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
object.setData(TEST_STRING);
context.getApi().putObject(containerName, object,
withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
withAcl(CannedAccessPolicy.PUBLIC_READ));
URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s", containerName, key));
Utils.toStringAndClose(url.openStream());
@ -126,8 +125,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
validateContent(containerName, sourceKey);
context.getApi().copyObject(containerName, sourceKey, destinationContainer,
destinationKey, overrideAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
TimeUnit.SECONDS);
destinationKey, overrideAcl(CannedAccessPolicy.PUBLIC_READ));
validateContent(destinationContainer, destinationKey);
@ -154,14 +152,13 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
object.setData("");
// Public Read-Write object
context.getApi().putObject(containerName, object,
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ_WRITE)).get(10,
TimeUnit.SECONDS);
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ_WRITE));
assertConsistencyAware(new Runnable() {
public void run() {
try {
AccessControlList acl = context.getApi().getObjectACL(containerName,
publicReadWriteObjectKey).get(10, TimeUnit.SECONDS);
publicReadWriteObjectKey);
assertEquals(acl.getGrants().size(), 3);
assertEquals(acl.getPermissions(GroupGranteeURI.ALL_USERS).size(), 2);
assertTrue(acl.getOwner() != null);
@ -191,8 +188,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
// Private object
addBlobToContainer(containerName, objectKey);
AccessControlList acl = context.getApi().getObjectACL(containerName, objectKey).get(10,
TimeUnit.SECONDS);
AccessControlList acl = context.getApi().getObjectACL(containerName, objectKey);
String ownerId = acl.getOwner().getId();
assertEquals(acl.getGrants().size(), 1);
@ -200,11 +196,10 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
addGrantsToACL(acl);
assertEquals(acl.getGrants().size(), 4);
assertTrue(context.getApi().putObjectACL(containerName, objectKey, acl).get(10,
TimeUnit.SECONDS));
assertTrue(context.getApi().putObjectACL(containerName, objectKey, acl));
// Confirm that the updated ACL has stuck.
acl = context.getApi().getObjectACL(containerName, objectKey).get(10, TimeUnit.SECONDS);
acl = context.getApi().getObjectACL(containerName, objectKey);
checkGrants(acl);
/*
@ -218,11 +213,10 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
// Update the object's ACL settings
assertTrue(context.getApi().putObjectACL(containerName, objectKey, acl).get(10,
TimeUnit.SECONDS));
assertTrue(context.getApi().putObjectACL(containerName, objectKey, acl));
// Confirm that the updated ACL has stuck
acl = context.getApi().getObjectACL(containerName, objectKey).get(10, TimeUnit.SECONDS);
acl = context.getApi().getObjectACL(containerName, objectKey);
assertEquals(acl.getGrants().size(), 1);
assertEquals(acl.getPermissions(ownerId).size(), 0);
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
@ -239,8 +233,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
try {
// Private object
addBlobToContainer(containerName, privateObjectKey);
AccessControlList acl = context.getApi().getObjectACL(containerName, privateObjectKey)
.get(10, TimeUnit.SECONDS);
AccessControlList acl = context.getApi().getObjectACL(containerName, privateObjectKey);
assertEquals(acl.getGrants().size(), 1);
assertTrue(acl.getOwner() != null);
@ -261,14 +254,13 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
object.getMetadata().setKey(publicReadObjectKey);
object.setData("");
context.getApi().putObject(containerName, object,
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ)).get(10,
TimeUnit.SECONDS);
new PutObjectOptions().withAcl(CannedAccessPolicy.PUBLIC_READ));
assertConsistencyAware(new Runnable() {
public void run() {
try {
AccessControlList acl = context.getApi().getObjectACL(containerName,
publicReadObjectKey).get(10, TimeUnit.SECONDS);
publicReadObjectKey);
assertEquals(acl.getGrants().size(), 2);
assertEquals(acl.getPermissions(GroupGranteeURI.ALL_USERS).size(), 1);
@ -288,20 +280,18 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
}
protected String addBlobToContainer(String sourceContainer, String key)
throws InterruptedException, ExecutionException, TimeoutException, IOException {
protected String addBlobToContainer(String sourceContainer, String key) {
S3Object sourceObject = context.getApi().newS3Object();
sourceObject.getMetadata().setKey(key);
sourceObject.getMetadata().setContentType("text/xml");
sourceObject.setData(TEST_STRING);
return context.getApi().putObject(sourceContainer, sourceObject).get(10, TimeUnit.SECONDS);
return context.getApi().putObject(sourceContainer, sourceObject);
}
protected S3Object validateObject(String sourceContainer, String key)
throws InterruptedException, ExecutionException, TimeoutException, IOException {
assertConsistencyAwareContainerSize(sourceContainer, 1);
S3Object newObject = context.getApi().getObject(sourceContainer, key).get(30,
TimeUnit.SECONDS);
S3Object newObject = context.getApi().getObject(sourceContainer, key);
assert newObject != null;
assertEquals(Utils.toStringAndClose((InputStream) newObject.getData()), TEST_STRING);
return newObject;
@ -317,7 +307,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
object.getMetadata().setContentDisposition("attachment; filename=hello.txt");
String containerName = getContainerName();
try {
context.getApi().putObject(containerName, object).get(10, TimeUnit.SECONDS);
context.getApi().putObject(containerName, object);
S3Object newObject = validateObject(containerName, key);
@ -339,7 +329,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
object.getMetadata().setContentEncoding("x-compress");
String containerName = getContainerName();
try {
context.getApi().putObject(containerName, object).get(10, TimeUnit.SECONDS);
context.getApi().putObject(containerName, object);
S3Object newObject = validateObject(containerName, key);
assertEquals(newObject.getMetadata().getContentEncoding(), "x-compress");
@ -356,8 +346,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
addToContainerAndValidate(containerName, sourceKey);
context.getApi()
.copyObject(containerName, sourceKey, destinationContainer, destinationKey).get(
10, TimeUnit.SECONDS);
.copyObject(containerName, sourceKey, destinationContainer, destinationKey);
validateContent(destinationContainer, destinationKey);
} finally {
@ -385,19 +374,14 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
DateTime after = new DateTime().plusSeconds(1);
context.getApi().copyObject(containerName, sourceKey + "mod", destinationContainer,
destinationKey, ifSourceModifiedSince(before)).get(10, TimeUnit.SECONDS);
destinationKey, ifSourceModifiedSince(before));
validateContent(destinationContainer, destinationKey);
try {
context.getApi().copyObject(containerName, sourceKey + "mod", destinationContainer,
destinationKey, ifSourceModifiedSince(after)).get(10, TimeUnit.SECONDS);
} catch (ExecutionException e) {
if (e.getCause() instanceof HttpResponseException) {
HttpResponseException ex = (HttpResponseException) e.getCause();
assertEquals(ex.getResponse().getStatusCode(), 412);
} else {
throw e;
}
destinationKey, ifSourceModifiedSince(after));
} catch (HttpResponseException ex) {
assertEquals(ex.getResponse().getStatusCode(), 412);
}
} finally {
returnContainer(containerName);
@ -417,14 +401,13 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
DateTime after = new DateTime().plusSeconds(1);
context.getApi().copyObject(containerName, sourceKey + "un", destinationContainer,
destinationKey, ifSourceUnmodifiedSince(after)).get(10, TimeUnit.SECONDS);
destinationKey, ifSourceUnmodifiedSince(after));
validateContent(destinationContainer, destinationKey);
try {
context.getApi().copyObject(containerName, sourceKey + "un", destinationContainer,
destinationKey, ifSourceModifiedSince(before)).get(10, TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
destinationKey, ifSourceModifiedSince(before));
} catch (HttpResponseException ex) {
assertEquals(ex.getResponse().getStatusCode(), 412);
}
} finally {
@ -441,14 +424,13 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
String goodETag = addToContainerAndValidate(containerName, sourceKey);
context.getApi().copyObject(containerName, sourceKey, destinationContainer,
destinationKey, ifSourceETagMatches(goodETag)).get(10, TimeUnit.SECONDS);
destinationKey, ifSourceETagMatches(goodETag));
validateContent(destinationContainer, destinationKey);
try {
context.getApi().copyObject(containerName, sourceKey, destinationContainer,
destinationKey, ifSourceETagMatches("setsds")).get(10, TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
destinationKey, ifSourceETagMatches("setsds"));
} catch (HttpResponseException ex) {
assertEquals(ex.getResponse().getStatusCode(), 412);
}
} finally {
@ -465,14 +447,13 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
String goodETag = addToContainerAndValidate(containerName, sourceKey);
context.getApi().copyObject(containerName, sourceKey, destinationContainer,
destinationKey, ifSourceETagDoesntMatch("asfasdf")).get(10, TimeUnit.SECONDS);
destinationKey, ifSourceETagDoesntMatch("asfasdf"));
validateContent(destinationContainer, destinationKey);
try {
context.getApi().copyObject(containerName, sourceKey, destinationContainer,
destinationKey, ifSourceETagDoesntMatch(goodETag)).get(10, TimeUnit.SECONDS);
} catch (ExecutionException e) {
HttpResponseException ex = (HttpResponseException) e.getCause();
destinationKey, ifSourceETagDoesntMatch(goodETag));
} catch (HttpResponseException ex) {
assertEquals(ex.getResponse().getStatusCode(), 412);
}
} finally {
@ -493,7 +474,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
metadata.put("adrian", "cole");
context.getApi().copyObject(containerName, sourceKey, destinationContainer,
destinationKey, overrideMetadataWith(metadata)).get(10, TimeUnit.SECONDS);
destinationKey, overrideMetadataWith(metadata));
validateContent(destinationContainer, destinationKey);
@ -512,8 +493,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
ExecutionException, TimeoutException, IOException {
String containerName = getContainerName();
try {
AccessControlList acl = context.getApi().getBucketACL(containerName).get(10,
TimeUnit.SECONDS);
AccessControlList acl = context.getApi().getBucketACL(containerName);
assertEquals(acl.getGrants().size(), 1);
assertTrue(acl.getOwner() != null);
String ownerId = acl.getOwner().getId();
@ -529,18 +509,17 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
String containerName = getContainerName();
try {
// Confirm the container is private
AccessControlList acl = context.getApi().getBucketACL(containerName).get(10,
TimeUnit.SECONDS);
AccessControlList acl = context.getApi().getBucketACL(containerName);
String ownerId = acl.getOwner().getId();
assertEquals(acl.getGrants().size(), 1);
assertTrue(acl.hasPermission(ownerId, Permission.FULL_CONTROL));
addGrantsToACL(acl);
assertEquals(acl.getGrants().size(), 4);
assertTrue(context.getApi().putBucketACL(containerName, acl).get(10, TimeUnit.SECONDS));
assertTrue(context.getApi().putBucketACL(containerName, acl));
// Confirm that the updated ACL has stuck.
acl = context.getApi().getBucketACL(containerName).get(10, TimeUnit.SECONDS);
acl = context.getApi().getBucketACL(containerName);
checkGrants(acl);
} finally {
destroyContainer(containerName);
@ -571,9 +550,8 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
String containerName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(containerName,
withBucketAcl(CannedAccessPolicy.PUBLIC_READ)).get(10, TimeUnit.SECONDS);
AccessControlList acl = context.getApi().getBucketACL(containerName).get(10,
TimeUnit.SECONDS);
withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
AccessControlList acl = context.getApi().getBucketACL(containerName);
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl.toString());
// TODO: I believe that the following should work based on the above acl assertion passing.
// However, it fails on 403
@ -603,13 +581,11 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
final String containerName = getScratchContainerName();
try {
context.getApi().putBucketIfNotExists(containerName + "eu",
createIn(LocationConstraint.EU).withBucketAcl(CannedAccessPolicy.PUBLIC_READ))
.get(30, TimeUnit.SECONDS);
createIn(LocationConstraint.EU).withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
assertConsistencyAware(new Runnable() {
public void run() {
try {
AccessControlList acl = context.getApi().getBucketACL(containerName + "eu").get(
30, TimeUnit.SECONDS);
AccessControlList acl = context.getApi().getBucketACL(containerName + "eu");
assertTrue(acl.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ), acl
.toString());
} catch (Exception e) {
@ -629,8 +605,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
void containerExists() throws Exception {
String containerName = getContainerName();
try {
SortedSet<BucketMetadata> list = context.getApi().listOwnedBuckets().get(10,
TimeUnit.SECONDS);
SortedSet<BucketMetadata> list = context.getApi().listOwnedBuckets();
BucketMetadata firstContainer = list.first();
BucketMetadata toMatch = new BucketMetadata(containerName, new DateTime(), firstContainer
.getOwner());
@ -640,23 +615,22 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
}
}
protected void addAlphabetUnderRoot(String containerName) throws InterruptedException,
ExecutionException, TimeoutException {
protected void addAlphabetUnderRoot(String containerName) {
for (char letter = 'a'; letter <= 'z'; letter++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(letter + "");
blob.setData(letter + "content");
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
context.getApi().putObject(containerName, blob);
}
}
public void testListContainerMarker() throws InterruptedException, ExecutionException,
TimeoutException, UnsupportedEncodingException {
TimeoutException {
String containerName = getContainerName();
try {
addAlphabetUnderRoot(containerName);
ListBucketResponse container = context.getApi()
.listBucket(containerName, afterMarker("y")).get(10, TimeUnit.SECONDS);
.listBucket(containerName, afterMarker("y"));
assertEquals(container.getMarker(), "y");
assert !container.isTruncated();
assertEquals(container.size(), 1);
@ -672,8 +646,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
String prefix = "apps";
addTenObjectsUnderPrefix(containerName, prefix);
add15UnderRoot(containerName);
ListBucketResponse container = context.getApi().listBucket(containerName, delimiter("/"))
.get(10, TimeUnit.SECONDS);
ListBucketResponse container = context.getApi().listBucket(containerName, delimiter("/"));
assertEquals(container.getDelimiter(), "/");
assert !container.isTruncated();
assertEquals(container.size(), 15);
@ -693,7 +666,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
add15UnderRoot(containerName);
ListBucketResponse container = context.getApi().listBucket(containerName,
withPrefix("apps/")).get(10, TimeUnit.SECONDS);
withPrefix("apps/"));
assert !container.isTruncated();
assertEquals(container.size(), 10);
assertEquals(container.getPrefix(), "apps/");
@ -708,8 +681,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
String containerName = getContainerName();
try {
addAlphabetUnderRoot(containerName);
ListBucketResponse container = context.getApi().listBucket(containerName, maxResults(5))
.get(10, TimeUnit.SECONDS);
ListBucketResponse container = context.getApi().listBucket(containerName, maxResults(5));
assertEquals(container.getMaxKeys(), 5);
assert container.isTruncated();
assertEquals(container.size(), 5);
@ -718,23 +690,21 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
}
}
protected void add15UnderRoot(String containerName) throws InterruptedException,
ExecutionException, TimeoutException {
protected void add15UnderRoot(String containerName) {
for (int i = 0; i < 15; i++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(i + "");
blob.setData(i + "content");
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
context.getApi().putObject(containerName, blob);
}
}
protected void addTenObjectsUnderPrefix(String containerName, String prefix)
throws InterruptedException, ExecutionException, TimeoutException {
protected void addTenObjectsUnderPrefix(String containerName, String prefix) {
for (int i = 0; i < 10; i++) {
S3Object blob = context.getApi().newS3Object();
blob.getMetadata().setKey(prefix + "/" + i);
blob.setData(i + "content");
context.getApi().putObject(containerName, blob).get(10, TimeUnit.SECONDS);
context.getApi().putObject(containerName, blob);
}
}
}

View File

@ -82,12 +82,12 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "s3.S3ClientTest")
public class S3ClientTest extends RestClientTest<S3Client> {
public class S3ClientTest extends RestClientTest<S3AsyncClient> {
public void testListBucket() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("listBucket", String.class, Array.newInstance(
Method method = S3AsyncClient.class.getMethod("listBucket", String.class, Array.newInstance(
ListBucketOptions.class, 0).getClass());
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket");
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
@ -101,8 +101,8 @@ public class S3ClientTest extends RestClientTest<S3Client> {
}
public void testBucketExists() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("bucketExists", String.class);
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
Method method = S3AsyncClient.class.getMethod("bucketExists", String.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket");
assertRequestLineEquals(httpMethod, "HEAD http://bucket.stub:8080/?max-keys=0 HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
@ -117,10 +117,10 @@ public class S3ClientTest extends RestClientTest<S3Client> {
public void testCopyObject() throws ArrayIndexOutOfBoundsException, SecurityException,
IllegalArgumentException, NoSuchMethodException, IOException {
Method method = S3Client.class
Method method = S3AsyncClient.class
.getMethod("copyObject", String.class, String.class, String.class, String.class,
Array.newInstance(CopyObjectOptions.class, 0).getClass());
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "sourceBucket",
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "sourceBucket",
"sourceObject", "destinationBucket", "destinationObject");
assertRequestLineEquals(httpMethod,
@ -138,8 +138,8 @@ public class S3ClientTest extends RestClientTest<S3Client> {
public void testDeleteBucketIfEmpty() throws SecurityException, NoSuchMethodException,
IOException {
Method method = S3Client.class.getMethod("deleteBucketIfEmpty", String.class);
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
Method method = S3AsyncClient.class.getMethod("deleteBucketIfEmpty", String.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket");
assertRequestLineEquals(httpMethod, "DELETE http://bucket.stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
@ -153,8 +153,8 @@ public class S3ClientTest extends RestClientTest<S3Client> {
}
public void testDeleteObject() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("deleteObject", String.class, String.class);
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
Method method = S3AsyncClient.class.getMethod("deleteObject", String.class, String.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket",
"object");
assertRequestLineEquals(httpMethod, "DELETE http://bucket.stub:8080/object HTTP/1.1");
@ -170,8 +170,8 @@ public class S3ClientTest extends RestClientTest<S3Client> {
public void testGetBucketACL() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("getBucketACL", String.class);
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
Method method = S3AsyncClient.class.getMethod("getBucketACL", String.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket");
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/?acl HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: bucket.stub\n");
@ -186,9 +186,9 @@ public class S3ClientTest extends RestClientTest<S3Client> {
public void testGetObject() throws ArrayIndexOutOfBoundsException, SecurityException,
IllegalArgumentException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("getObject", String.class, String.class, Array
Method method = S3AsyncClient.class.getMethod("getObject", String.class, String.class, Array
.newInstance(GetOptions.class, 0).getClass());
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket",
"object");
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/object HTTP/1.1");
@ -205,8 +205,8 @@ public class S3ClientTest extends RestClientTest<S3Client> {
public void testGetObjectACL() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("getObjectACL", String.class, String.class);
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
Method method = S3AsyncClient.class.getMethod("getObjectACL", String.class, String.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket",
"object");
assertRequestLineEquals(httpMethod, "GET http://bucket.stub:8080/object?acl HTTP/1.1");
@ -222,8 +222,8 @@ public class S3ClientTest extends RestClientTest<S3Client> {
public void testHeadObject() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("headObject", String.class, String.class);
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
Method method = S3AsyncClient.class.getMethod("headObject", String.class, String.class);
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket",
"object");
assertRequestLineEquals(httpMethod, "HEAD http://bucket.stub:8080/object HTTP/1.1");
@ -238,8 +238,8 @@ public class S3ClientTest extends RestClientTest<S3Client> {
}
public void testListOwnedBuckets() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("listOwnedBuckets");
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method);
Method method = S3AsyncClient.class.getMethod("listOwnedBuckets");
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method);
assertRequestLineEquals(httpMethod, "GET http://stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Host: stub\n");
@ -253,14 +253,14 @@ public class S3ClientTest extends RestClientTest<S3Client> {
}
public void testNewS3Object() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("newS3Object");
Method method = S3AsyncClient.class.getMethod("newS3Object");
assertEquals(method.getReturnType(), S3Object.class);
}
public void testPutBucketACL() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("putBucketACL", String.class,
Method method = S3AsyncClient.class.getMethod("putBucketACL", String.class,
AccessControlList.class);
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket",
AccessControlList.fromCannedAccessPolicy(CannedAccessPolicy.PRIVATE, "1234"));
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/?acl HTTP/1.1");
@ -279,9 +279,9 @@ public class S3ClientTest extends RestClientTest<S3Client> {
public void testPutBucketIfNotExists() throws ArrayIndexOutOfBoundsException, SecurityException,
IllegalArgumentException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("putBucketIfNotExists", String.class, Array
Method method = S3AsyncClient.class.getMethod("putBucketIfNotExists", String.class, Array
.newInstance(PutBucketOptions.class, 0).getClass());
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket");
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket");
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/ HTTP/1.1");
assertHeadersEqual(httpMethod, "Content-Length: 0\nHost: bucket.stub\n");
@ -297,9 +297,9 @@ public class S3ClientTest extends RestClientTest<S3Client> {
public void testPutObject() throws ArrayIndexOutOfBoundsException, SecurityException,
IllegalArgumentException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("putObject", String.class, S3Object.class, Array
Method method = S3AsyncClient.class.getMethod("putObject", String.class, S3Object.class, Array
.newInstance(PutObjectOptions.class, 0).getClass());
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket",
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket",
blobToS3Object.apply(BindBlobToMultipartFormTest.TEST_BLOB));
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/hello HTTP/1.1");
@ -315,9 +315,9 @@ public class S3ClientTest extends RestClientTest<S3Client> {
}
public void testPutObjectACL() throws SecurityException, NoSuchMethodException, IOException {
Method method = S3Client.class.getMethod("putObjectACL", String.class, String.class,
Method method = S3AsyncClient.class.getMethod("putObjectACL", String.class, String.class,
AccessControlList.class);
GeneratedHttpRequest<S3Client> httpMethod = processor.createRequest(method, "bucket", "key",
GeneratedHttpRequest<S3AsyncClient> httpMethod = processor.createRequest(method, "bucket", "key",
AccessControlList.fromCannedAccessPolicy(CannedAccessPolicy.PRIVATE, "1234"));
assertRequestLineEquals(httpMethod, "PUT http://bucket.stub:8080/key?acl HTTP/1.1");
@ -337,14 +337,14 @@ public class S3ClientTest extends RestClientTest<S3Client> {
BlobToObject blobToS3Object;
@Override
protected void checkFilters(GeneratedHttpRequest<S3Client> httpMethod) {
protected void checkFilters(GeneratedHttpRequest<S3AsyncClient> httpMethod) {
assertEquals(httpMethod.getFilters().size(), 1);
assertEquals(httpMethod.getFilters().get(0).getClass(), RequestAuthorizeSignature.class);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<S3Client>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<S3Client>>() {
protected TypeLiteral<RestAnnotationProcessor<S3AsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<S3AsyncClient>>() {
};
}

View File

@ -36,7 +36,7 @@ import org.jclouds.aws.s3.config.S3RestClientModule;
import org.jclouds.aws.s3.config.S3StubClientModule;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.internal.S3ObjectImpl;
import org.jclouds.aws.s3.internal.StubS3Client;
import org.jclouds.aws.s3.internal.StubS3AsyncClient;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.rest.RestContext;
@ -66,11 +66,11 @@ public class S3ContextBuilderTest {
}
public void testBuildContext() {
RestContext<S3Client> context = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret")
.build()).withModules(new S3StubClientModule()).buildContext();
RestContext<S3AsyncClient, S3Client> context = new S3ContextBuilder(new S3PropertiesBuilder(
"id", "secret").build()).withModules(new S3StubClientModule()).buildContext();
assertEquals(context.getClass(), RestContextImpl.class);
assertEquals(context.getApi().getClass(), StubS3Client.class);
assertEquals(context.getApi().newS3Object().getClass(), S3ObjectImpl.class);
assertEquals(context.getAsyncApi().getClass(), StubS3AsyncClient.class);
assertEquals(context.getAsyncApi().newS3Object().getClass(), S3ObjectImpl.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("https://localhost/s3stub"));
}
@ -78,7 +78,7 @@ public class S3ContextBuilderTest {
public void testBuildInjector() {
Injector i = new S3ContextBuilder(new S3PropertiesBuilder("id", "secret").build())
.withModules(new S3StubClientModule()).buildInjector();
assert i.getInstance(Key.get(new TypeLiteral<RestContext<S3Client>>() {
assert i.getInstance(Key.get(new TypeLiteral<RestContext<S3AsyncClient, S3Client>>() {
})) != null;
assert i.getInstance(S3Object.class) != null;
assert i.getInstance(Blob.class) != null;

View File

@ -32,6 +32,7 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.S3PropertiesBuilder;
import org.jclouds.aws.s3.blobstore.config.S3BlobStoreContextModule;
@ -39,7 +40,7 @@ import org.jclouds.aws.s3.config.S3RestClientModule;
import org.jclouds.aws.s3.config.S3StubClientModule;
import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.domain.internal.S3ObjectImpl;
import org.jclouds.aws.s3.internal.StubS3Client;
import org.jclouds.aws.s3.internal.StubS3AsyncClient;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.internal.BlobImpl;
@ -69,13 +70,14 @@ public class S3BlobStoreContextBuilderTest {
}
public void testBuildContext() {
BlobStoreContext<S3Client> context = new S3BlobStoreContextBuilder(new S3PropertiesBuilder(
"id", "secret").build()).withModules(new S3StubClientModule()).buildContext();
BlobStoreContext<S3AsyncClient, S3Client> context = new S3BlobStoreContextBuilder(
new S3PropertiesBuilder("id", "secret").build()).withModules(
new S3StubClientModule()).buildContext();
assertEquals(context.getClass(), BlobStoreContextImpl.class);
assertEquals(context.getApi().getClass(), StubS3Client.class);
assertEquals(context.getBlobStore().getClass(), S3BlobStore.class);
assertEquals(context.getApi().newS3Object().getClass(), S3ObjectImpl.class);
assertEquals(context.getBlobStore().newBlob().getClass(), BlobImpl.class);
assertEquals(context.getAsyncApi().getClass(), StubS3AsyncClient.class);
assertEquals(context.getAsyncBlobStore().getClass(), S3AsyncBlobStore.class);
assertEquals(context.getAsyncApi().newS3Object().getClass(), S3ObjectImpl.class);
assertEquals(context.getAsyncBlobStore().newBlob().getClass(), BlobImpl.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("https://localhost/s3stub"));
}
@ -83,7 +85,7 @@ public class S3BlobStoreContextBuilderTest {
public void testBuildInjector() {
Injector i = new S3BlobStoreContextBuilder(new S3PropertiesBuilder("id", "secret").build())
.withModules(new S3StubClientModule()).buildInjector();
assert i.getInstance(Key.get(new TypeLiteral<BlobStoreContext<S3Client>>() {
assert i.getInstance(Key.get(new TypeLiteral<BlobStoreContext<S3AsyncClient, S3Client>>() {
})) != null;
assert i.getInstance(S3Object.class) != null;
assert i.getInstance(Blob.class) != null;

View File

@ -25,6 +25,7 @@ package org.jclouds.aws.s3.blobstore.config;
import static org.testng.Assert.assertEquals;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.config.S3StubClientModule;
import org.jclouds.aws.s3.reference.S3Constants;
@ -65,8 +66,8 @@ public class S3BlobStoreModuleTest {
@Test
void testContextImpl() {
BlobStoreContext<S3Client> context = createInjector().getInstance(
Key.get(new TypeLiteral<BlobStoreContext<S3Client>>() {
BlobStoreContext<S3AsyncClient, S3Client> context = createInjector().getInstance(
Key.get(new TypeLiteral<BlobStoreContext<S3AsyncClient, S3Client>>() {
}));
assertEquals(context.getClass(), BlobStoreContextImpl.class);
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.aws.s3.blobstore.integration;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
import org.testng.annotations.Test;
@ -33,6 +34,6 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "integration", "live" }, testName = "s3.S3BlobIntegrationTest")
public class S3BlobIntegrationTest extends BaseBlobIntegrationTest<S3Client> {
public class S3BlobIntegrationTest extends BaseBlobIntegrationTest<S3AsyncClient, S3Client> {
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.aws.s3.blobstore.integration;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
import org.testng.annotations.Test;
@ -33,6 +34,6 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "live" }, testName = "s3.S3BlobLiveTest")
public class S3BlobLiveTest extends BaseBlobLiveTest<S3Client> {
public class S3BlobLiveTest extends BaseBlobLiveTest<S3AsyncClient, S3Client> {
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.aws.s3.blobstore.integration;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest;
import org.testng.annotations.Test;
@ -31,6 +32,6 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "integration", "live" }, testName = "s3.S3BlobMapIntegrationTest")
public class S3BlobMapIntegrationTest extends BaseBlobMapIntegrationTest<S3Client> {
public class S3BlobMapIntegrationTest extends BaseBlobMapIntegrationTest<S3AsyncClient, S3Client> {
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.aws.s3.blobstore.integration;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
import org.testng.annotations.Test;
@ -32,6 +33,7 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "integration", "live" }, testName = "s3.S3ContainerIntegrationTest")
public class S3ContainerIntegrationTest extends BaseContainerIntegrationTest<S3Client> {
public class S3ContainerIntegrationTest extends
BaseContainerIntegrationTest<S3AsyncClient, S3Client> {
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.aws.s3.blobstore.integration;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
import org.testng.annotations.Test;
@ -32,6 +33,6 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "live" }, testName = "s3.S3ContainerLiveTest")
public class S3ContainerLiveTest extends BaseContainerLiveTest<S3Client> {
public class S3ContainerLiveTest extends BaseContainerLiveTest<S3AsyncClient, S3Client> {
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.aws.s3.blobstore.integration;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest;
import org.testng.annotations.Test;
@ -32,6 +33,6 @@ import org.testng.annotations.Test;
*/
@Test(groups = { "integration", "live" }, testName = "s3.S3InputStreamMapIntegrationTest")
public class S3InputStreamMapIntegrationTest extends
BaseInputStreamMapIntegrationTest<S3Client> {
BaseInputStreamMapIntegrationTest<S3AsyncClient, S3Client> {
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.aws.s3.blobstore.integration;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest;
import org.testng.annotations.Test;
@ -31,6 +32,6 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
@Test(groups = { "integration", "live" }, testName = "s3.S3ServiceIntegrationTest")
public class S3ServiceIntegrationTest extends BaseServiceIntegrationTest<S3Client> {
public class S3ServiceIntegrationTest extends BaseServiceIntegrationTest<S3AsyncClient, S3Client> {
}

View File

@ -23,6 +23,7 @@
*/
package org.jclouds.aws.s3.blobstore.integration;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.S3PropertiesBuilder;
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextBuilder;
@ -39,18 +40,18 @@ import com.google.inject.Module;
*
* @author Adrian Cole
*/
public class S3TestInitializer extends BaseTestInitializer<S3Client> {
public class S3TestInitializer extends BaseTestInitializer<S3AsyncClient, S3Client> {
@Override
protected BlobStoreContext<S3Client> createLiveContext(Module configurationModule, String url,
String app, String account, String key) {
protected BlobStoreContext<S3AsyncClient, S3Client> createLiveContext(
Module configurationModule, String url, String app, String account, String key) {
BaseBlobStoreIntegrationTest.SANITY_CHECK_RETURNED_BUCKET_NAME = true;
return new S3BlobStoreContextBuilder(new S3PropertiesBuilder(account, key).relaxSSLHostname()
.build()).withModules(configurationModule, new Log4JLoggingModule()).buildContext();
}
@Override
protected BlobStoreContext<S3Client> createStubContext() {
protected BlobStoreContext<S3AsyncClient, S3Client> createStubContext() {
return S3BlobStoreContextFactory.createContext("user", "pass", new S3StubClientModule());
}

View File

@ -25,6 +25,7 @@ package org.jclouds.aws.s3.config;
import static org.testng.Assert.assertEquals;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.concurrent.WithinThreadExecutorService;
@ -64,8 +65,9 @@ public class S3ContextModuleTest {
@Test
void testContextImpl() {
RestContext<S3Client> handler = createInjector().getInstance(Key.get(new TypeLiteral<RestContext<S3Client>>() {
}));
RestContext<S3AsyncClient, S3Client> handler = createInjector().getInstance(
Key.get(new TypeLiteral<RestContext<S3AsyncClient, S3Client>>() {
}));
assertEquals(handler.getClass(), RestContextImpl.class);
}

View File

@ -25,14 +25,19 @@ package org.jclouds.aws.s3.config;
import java.net.URI;
import javax.inject.Singleton;
import org.jclouds.aws.s3.S3;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.internal.StubS3Client;
import org.jclouds.aws.s3.internal.StubS3AsyncClient;
import org.jclouds.blobstore.integration.config.StubBlobStoreModule;
import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.http.functions.config.ParserModule;
import org.jclouds.rest.ConfiguresRestClient;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* adds a stub alternative to invoking S3
@ -45,7 +50,14 @@ public class S3StubClientModule extends AbstractModule {
protected void configure() {
install(new ParserModule());
install(new StubBlobStoreModule());
bind(S3Client.class).to(StubS3Client.class).asEagerSingleton();
bind(S3AsyncClient.class).to(StubS3AsyncClient.class).asEagerSingleton();
bind(URI.class).annotatedWith(S3.class).toInstance(URI.create("https://localhost/s3stub"));
}
@Provides
@Singleton
public S3Client provideClient(S3AsyncClient client) throws IllegalArgumentException,
SecurityException, NoSuchMethodException {
return SyncProxy.create(S3Client.class, client);
}
}

View File

@ -34,8 +34,8 @@ import java.util.concurrent.Future;
import javax.inject.Inject;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.S3BlobStore;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.blobstore.S3AsyncBlobStore;
import org.jclouds.aws.s3.blobstore.functions.BlobToObject;
import org.jclouds.aws.s3.blobstore.functions.BlobToObjectMetadata;
import org.jclouds.aws.s3.blobstore.functions.BucketToContainerListOptions;
@ -58,10 +58,11 @@ import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.attr.ConsistencyModels;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.MutableBlobMetadata;
import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions;
import org.jclouds.blobstore.integration.internal.StubBlobStore;
import org.jclouds.blobstore.integration.internal.StubBlobStore.FutureBase;
import org.jclouds.blobstore.integration.internal.StubAsyncBlobStore;
import org.jclouds.blobstore.integration.internal.StubAsyncBlobStore.FutureBase;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.http.options.GetOptions;
@ -74,16 +75,16 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
* Implementation of {@link S3BlobStore} which keeps all data in a local Map object.
* Implementation of {@link S3AsyncBlobStore} which keeps all data in a local Map object.
*
* @author Adrian Cole
* @author James Murty
*/
@ConsistencyModel(ConsistencyModels.STRICT)
public class StubS3Client implements S3Client {
public class StubS3AsyncClient implements S3AsyncClient {
private final DateService dateService;
private final HttpGetOptionsListToGetOptions httpGetOptionsConverter;
private final StubBlobStore blobStore;
private final StubAsyncBlobStore blobStore;
private final LoggerFactory logFactory;
private final S3Object.Factory objectProvider;
private final Blob.Factory blobProvider;
@ -94,7 +95,7 @@ public class StubS3Client implements S3Client {
private final ResourceToBucketList resource2BucketList;
@Inject
private StubS3Client(StubBlobStore blobStore, LoggerFactory logFactory,
private StubS3AsyncClient(StubAsyncBlobStore blobStore, LoggerFactory logFactory,
ConcurrentMap<String, ConcurrentMap<String, Blob>> containerToBlobs,
DateService dateService, S3Object.Factory objectProvider, Blob.Factory blobProvider,
HttpGetOptionsListToGetOptions httpGetOptionsConverter, ObjectToBlob object2Blob,
@ -279,8 +280,12 @@ public class StubS3Client implements S3Client {
};
}
public boolean bucketExists(String bucketName) {
return blobStore.getContainerToBlobs().containsKey(bucketName);
public Future<Boolean> bucketExists(final String bucketName) {
return new FutureBase<Boolean>() {
public Boolean get() throws InterruptedException, ExecutionException {
return blobStore.getContainerToBlobs().containsKey(bucketName);
}
};
}
public Future<Boolean> deleteBucketIfEmpty(String bucketName) {
@ -297,8 +302,17 @@ public class StubS3Client implements S3Client {
return wrapFuture(blobStore.getBlob(bucketName, key, getOptions), blob2Object);
}
public ObjectMetadata headObject(String bucketName, String key) {
return blob2ObjectMetadata.apply(blobStore.blobMetadata(bucketName, key));
public Future<ObjectMetadata> headObject(String bucketName, String key) {
return wrapFuture(blobStore.blobMetadata(bucketName, key),
new Function<BlobMetadata, ObjectMetadata>() {
@Override
public ObjectMetadata apply(BlobMetadata from) {
return blob2ObjectMetadata.apply(from);
}
});
}
public Future<? extends SortedSet<BucketMetadata>> listOwnedBuckets() {

View File

@ -23,11 +23,6 @@
*/
package org.jclouds.aws.s3.samples;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextFactory;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
@ -49,8 +44,7 @@ public class MainApp {
public static String INVALID_SYNTAX = "Invalid number of parameters. Syntax is: \"accesskeyid\" \"secretkey\" \"bucketName\" ";
@SuppressWarnings("unchecked")
public static void main(String[] args) throws InterruptedException, ExecutionException,
TimeoutException, IOException {
public static void main(String[] args) {
if (args.length < PARAMETERS)
throw new IllegalArgumentException(INVALID_SYNTAX);
@ -67,15 +61,15 @@ public class MainApp {
// Create Container
BlobStore blobStore = context.getBlobStore();
blobStore.createContainer(containerName).get(10, TimeUnit.SECONDS);
blobStore.createContainer(containerName);
Blob blob = context.getBlobStore().newBlob();
Blob blob = blobStore.newBlob();
blob.getMetadata().setName("test");
blob.setData("testdata");
blobStore.putBlob(containerName, blob).get(10, TimeUnit.SECONDS);
blobStore.putBlob(containerName, blob);
// List Container
for (ResourceMetadata resourceMd : blobStore.list().get(10, TimeUnit.SECONDS)) {
for (ResourceMetadata resourceMd : blobStore.list()) {
if (resourceMd.getType() == ResourceType.CONTAINER
|| resourceMd.getType() == ResourceType.FOLDER) {
System.out.printf(" %s: %s entries%n", resourceMd.getName(), context

View File

@ -53,14 +53,14 @@ import com.google.common.collect.Sets;
public class GetAllContainersController extends HttpServlet {
private static final long serialVersionUID = 1L;
private Map<String, BlobStoreContext<?>> contexts;
private Map<String, BlobStoreContext<?,?>> contexts;
private final BlobStoreContextToContainerResult blobStoreContextToContainerResult;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public GetAllContainersController(Map<String, BlobStoreContext<?>> contexts,
public GetAllContainersController(Map<String, BlobStoreContext<?,?>> contexts,
BlobStoreContextToContainerResult blobStoreContextToContainerResult) {
this.contexts = contexts;
this.blobStoreContextToContainerResult = blobStoreContextToContainerResult;

View File

@ -55,7 +55,7 @@ import com.google.inject.servlet.ServletModule;
*/
public class GuiceServletConfig extends GuiceServletContextListener {
private Map<String, BlobStoreContext<?>> contexts;
private Map<String, BlobStoreContext<?, ?>> contexts;
@SuppressWarnings("unchecked")
@Override
@ -67,10 +67,10 @@ public class GuiceServletConfig extends GuiceServletContextListener {
contexts = Maps.newHashMap();
for (String className : list) {
try {
Class<BlobStoreContextBuilder<?>> builderClass;
builderClass = (Class<BlobStoreContextBuilder<?>>) Class.forName(className);
Class<BlobStoreContextBuilder<?, ?>> builderClass;
builderClass = (Class<BlobStoreContextBuilder<?, ?>>) Class.forName(className);
String name = builderClass.getSimpleName().replaceAll("BlobStoreContextBuilder", "");
Constructor<BlobStoreContextBuilder<?>> constructor = builderClass
Constructor<BlobStoreContextBuilder<?, ?>> constructor = builderClass
.getConstructor(Properties.class);
contexts.put(name, constructor.newInstance(props).withModules(
new GaeHttpCommandExecutorServiceModule()).buildContext());
@ -100,7 +100,7 @@ public class GuiceServletConfig extends GuiceServletContextListener {
return Guice.createInjector(new ServletModule() {
@Override
protected void configureServlets() {
bind(new TypeLiteral<Map<String, BlobStoreContext<?>>>() {
bind(new TypeLiteral<Map<String, BlobStoreContext<?, ?>>>() {
}).toInstance(GuiceServletConfig.this.contexts);
serve("*.blobstore").with(GetAllContainersController.class);
requestInjection(this);
@ -112,7 +112,7 @@ public class GuiceServletConfig extends GuiceServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
for (BlobStoreContext<?> context : contexts.values()) {
for (BlobStoreContext<?, ?> context : contexts.values()) {
context.close();
}
super.contextDestroyed(servletContextEvent);

View File

@ -24,7 +24,6 @@
package org.jclouds.samples.googleappengine.functions;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.inject.Inject;
@ -46,10 +45,10 @@ import com.google.common.collect.Sets;
public class BlobStoreContextToContainerResult implements Function<String, ContainerResult> {
private final class BuildContainerResult implements Function<ResourceMetadata, ContainerResult> {
private final String host;
private final BlobStoreContext<?> context;
private final BlobStoreContext<?, ?> context;
private final String contextName;
private BuildContainerResult(String host, BlobStoreContext<?> context, String contextName) {
private BuildContainerResult(String host, BlobStoreContext<?, ?> context, String contextName) {
this.host = host;
this.context = context;
this.contextName = contextName;
@ -74,24 +73,23 @@ public class BlobStoreContextToContainerResult implements Function<String, Conta
}
@Inject
private Map<String, BlobStoreContext<?>> contexts;
private Map<String, BlobStoreContext<?, ?>> contexts;
@Resource
protected Logger logger = Logger.NULL;
public ContainerResult apply(final String contextName) {
final BlobStoreContext<?> context = contexts.get(contextName);
final BlobStoreContext<?, ?> context = contexts.get(contextName);
final String host = context.getEndPoint().getHost();
try {
ResourceMetadata md = Iterables.getLast(Sets.newTreeSet(Iterables.filter(context
.getBlobStore().list().get(10, TimeUnit.SECONDS),
new Predicate<ResourceMetadata>() {
.getBlobStore().list(), new Predicate<ResourceMetadata>() {
public boolean apply(ResourceMetadata input) {
return input.getType() == ResourceType.CONTAINER;
}
public boolean apply(ResourceMetadata input) {
return input.getType() == ResourceType.CONTAINER;
}
})));
})));
return new BuildContainerResult(host, context, contextName).apply(md);
} catch (Exception e) {
ContainerResult result = new ContainerResult(contextName, host, null, e.getMessage());

View File

@ -30,10 +30,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.blobstore.S3BlobStore;
import org.jclouds.aws.s3.blobstore.S3AsyncBlobStore;
import org.jclouds.aws.s3.blobstore.S3BlobStoreContextFactory;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.ObjectMetadata;
@ -64,11 +64,9 @@ public class JCloudsS3Service extends S3Service {
private static final long serialVersionUID = 1L;
private final BlobStoreContext<S3Client> context;
private final BlobStoreContext<S3AsyncClient, S3Client> context;
private final S3Client connection;
private final long requestTimeoutMilliseconds = 10000;
/**
* Initializes a JClouds context to S3.
*
@ -106,8 +104,7 @@ public class JCloudsS3Service extends S3Service {
CopyObjectOptions options = Util.convertCopyObjectOptions(acl, destinationMetadata,
ifModifiedSince, ifUnmodifiedSince, ifMatchTags, ifNoneMatchTags);
ObjectMetadata jcObjectMetadata = connection.copyObject(sourceBucketName, sourceObjectKey,
destinationBucketName, destinationObjectKey, options).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
destinationBucketName, destinationObjectKey, options);
Map map = new HashMap();
// Result fields returned when copy is successful.
@ -129,8 +126,7 @@ public class JCloudsS3Service extends S3Service {
throw new UnsupportedOperationException("Bucket ACL is not yet supported");
try {
if (connection.putBucketIfNotExists(bucketName).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS)) {
if (connection.putBucketIfNotExists(bucketName)) {
// Bucket created.
}
} catch (Exception e) {
@ -143,13 +139,12 @@ public class JCloudsS3Service extends S3Service {
/**
* {@inheritDoc}
*
* @see S3BlobStore#deleteContainer(String)
* @see S3AsyncBlobStore#deleteContainer(String)
*/
@Override
protected void deleteBucketImpl(String bucketName) throws S3ServiceException {
try {
connection.deleteBucketIfEmpty(bucketName).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
connection.deleteBucketIfEmpty(bucketName);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
throw new S3ServiceException("error deleting bucket: " + bucketName, e);
@ -159,13 +154,12 @@ public class JCloudsS3Service extends S3Service {
/**
* {@inheritDoc}
*
* @see S3BlobStore#removeBlob(String, String)
* @see S3AsyncBlobStore#removeBlob(String, String)
*/
@Override
protected void deleteObjectImpl(String bucketName, String objectKey) throws S3ServiceException {
try {
connection.deleteObject(bucketName, objectKey).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
connection.deleteObject(bucketName, objectKey);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
throw new S3ServiceException(String.format("error deleting object: %1$s:%2$s", bucketName,
@ -176,8 +170,7 @@ public class JCloudsS3Service extends S3Service {
@Override
protected AccessControlList getBucketAclImpl(String bucketName) throws S3ServiceException {
try {
org.jclouds.aws.s3.domain.AccessControlList jcACL = connection.getBucketACL(bucketName)
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
org.jclouds.aws.s3.domain.AccessControlList jcACL = connection.getBucketACL(bucketName);
return Util.convertAccessControlList(jcACL);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
@ -203,7 +196,7 @@ public class JCloudsS3Service extends S3Service {
throws S3ServiceException {
try {
org.jclouds.aws.s3.domain.AccessControlList jcACL = connection.getObjectACL(bucketName,
objectKey).get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
objectKey);
return Util.convertAccessControlList(jcACL);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
@ -240,8 +233,7 @@ public class JCloudsS3Service extends S3Service {
try {
GetOptions options = Util.convertGetObjectOptions(ifModifiedSince, ifUnmodifiedSince,
ifMatchTags, ifNoneMatchTags);
return Util.convertObject(connection.getObject(bucketName, objectKey, options).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS));
return Util.convertObject(connection.getObject(bucketName, objectKey, options));
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
throw new S3ServiceException(String.format("error retrieving object: %1$s:%2$s",
@ -265,7 +257,7 @@ public class JCloudsS3Service extends S3Service {
protected S3Bucket[] listAllBucketsImpl() throws S3ServiceException {
try {
SortedSet<org.jclouds.aws.s3.domain.BucketMetadata> jcBucketList = connection
.listOwnedBuckets().get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
.listOwnedBuckets();
return Util.convertBuckets(jcBucketList);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
@ -285,8 +277,7 @@ public class JCloudsS3Service extends S3Service {
ListBucketOptions options = Util.convertListObjectOptions(prefix, priorLastKey,
delimiter, (int) maxListingLength);
jcBucket = connection.listBucket(bucketName, options).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
jcBucket = connection.listBucket(bucketName, options);
jsObjects.addAll(Arrays.asList(Util.convertObjectHeads(jcBucket)));
commonPrefixes.addAll(jcBucket.getCommonPrefixes());
@ -325,8 +316,7 @@ public class JCloudsS3Service extends S3Service {
throws S3ServiceException {
try {
org.jclouds.aws.s3.domain.AccessControlList jcACL = Util.convertAccessControlList(jsACL);
connection.putBucketACL(bucketName, jcACL).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
connection.putBucketACL(bucketName, jcACL);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
throw new S3ServiceException("error putting bucket's ACL: " + bucketName, e);
@ -338,8 +328,7 @@ public class JCloudsS3Service extends S3Service {
throws S3ServiceException {
try {
org.jclouds.aws.s3.domain.AccessControlList jcACL = Util.convertAccessControlList(jsACL);
connection.putObjectACL(bucketName, objectKey, jcACL).get(requestTimeoutMilliseconds,
TimeUnit.MILLISECONDS);
connection.putObjectACL(bucketName, objectKey, jcACL);
} catch (Exception e) {
Utils.<S3ServiceException> rethrowIfRuntimeOrSameType(e);
throw new S3ServiceException("error putting object's ACL", e);
@ -350,9 +339,9 @@ public class JCloudsS3Service extends S3Service {
protected S3Object putObjectImpl(String bucketName, S3Object jsObject) throws S3ServiceException {
try {
PutObjectOptions options = Util.convertPutObjectOptions(jsObject.getAcl());
org.jclouds.aws.s3.domain.S3Object jcObject = Util.convertObject(jsObject, connection.newS3Object());
String eTag = connection.putObject(bucketName, jcObject, options).get(
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
org.jclouds.aws.s3.domain.S3Object jcObject = Util.convertObject(jsObject, connection
.newS3Object());
String eTag = connection.putObject(bucketName, jcObject, options);
jsObject.setETag(eTag);
return jsObject;
} catch (Exception e) {

View File

@ -38,12 +38,12 @@ import java.util.Iterator;
import java.util.Map;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.ws.rs.core.MediaType;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.S3AsyncClient;
import org.jclouds.aws.s3.S3Client;
import org.jclouds.aws.s3.domain.ListBucketResponse;
import org.jclouds.aws.s3.domain.AccessControlList.GroupGranteeURI;
@ -77,7 +77,7 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole
*/
@Test(groups = { "live" }, testName = "jets3t.JCloudsS3ServiceIntegrationTest")
public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3AsyncClient, S3Client> {
AWSCredentials credentials;
S3Service service;
@ -132,7 +132,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
try {
String objectKey = "key-testDeleteObjectImpl";
String objectValue = "test";
Blob blob = context.getBlobStore().newBlob();
Blob blob = context.getAsyncBlobStore().newBlob();
blob.getMetadata().setName(objectKey);
blob.setData(objectValue);
addBlobToContainer(bucketName, blob);
@ -153,7 +153,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
String metadataName = "metadata-name-1";
String metadataValue = "metadata-value-1";
Blob blob = context.getBlobStore().newBlob();
Blob blob = context.getAsyncBlobStore().newBlob();
blob.getMetadata().setName(objectKey);
blob.setData(objectValue);
blob.getMetadata().getUserMetadata().put(metadataName, metadataValue);
@ -180,7 +180,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
String metadataName = "metadata-name-2";
String metadataValue = "metadata-value-2";
Blob blob = context.getBlobStore().newBlob();
Blob blob = context.getAsyncBlobStore().newBlob();
blob.getMetadata().setName(objectKey);
blob.setData(objectValue);
blob.getMetadata().getUserMetadata().put(metadataName, metadataValue);
@ -209,7 +209,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
S3Bucket[] jsBuckets = service.listAllBuckets();
SortedSet<org.jclouds.aws.s3.domain.BucketMetadata> jcBuckets = context.getApi()
.listOwnedBuckets().get(10, TimeUnit.SECONDS);
.listOwnedBuckets();
assert jsBuckets.length == jcBuckets.size();
@ -360,7 +360,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
// Upload empty object
requestObject = new S3Object(objectKey);
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
jcObject = context.getApi().getObject(bucketName, objectKey).get(10, TimeUnit.SECONDS);
jcObject = context.getApi().getObject(bucketName, objectKey);
// TODO null keys from s3object! assertEquals(jcObject.getKey(), objectKey);
assertEquals(jcObject.getMetadata().getSize(), new Long(0));
assertEquals(jcObject.getMetadata().getContentType(), MediaType.APPLICATION_OCTET_STREAM);
@ -371,8 +371,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
// Upload unicode-named object
requestObject = new S3Object("₪n₪₪₪d₪-object");
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
jcObject = context.getApi().getObject(bucketName, requestObject.getKey()).get(10,
TimeUnit.SECONDS);
jcObject = context.getApi().getObject(bucketName, requestObject.getKey());
// TODO null keys from s3object! assertEquals(jcObject.getKey(), requestObject.getKey());
assertEquals(jcObject.getMetadata().getSize(), new Long(0));
assertEquals(jcObject.getMetadata().getContentType(), MediaType.APPLICATION_OCTET_STREAM);
@ -384,7 +383,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
String data = "This is my ₪n₪₪₪d₪ data";
requestObject = new S3Object(objectKey, data);
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
jcObject = context.getApi().getObject(bucketName, objectKey).get(10, TimeUnit.SECONDS);
jcObject = context.getApi().getObject(bucketName, objectKey);
assertEquals(jcObject.getMetadata().getSize(), new Long(data.getBytes("UTF-8").length));
assertTrue(jcObject.getMetadata().getContentType().startsWith("text/plain"));
assertEquals(jsResultObject.getContentLength(), data.getBytes("UTF-8").length);
@ -394,7 +393,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
requestObject = new S3Object(objectKey);
requestObject.addMetadata("x-amz-meta-" + "my-metadata-1", "value-1");
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
jcObject = context.getApi().getObject(bucketName, objectKey).get(10, TimeUnit.SECONDS);
jcObject = context.getApi().getObject(bucketName, objectKey);
assertEquals(jcObject.getMetadata().getUserMetadata().get("my-metadata-1"), "value-1");
assertEquals(jsResultObject.getMetadata("x-amz-meta-" + "my-metadata-1"), "value-1");
@ -403,7 +402,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
requestObject.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
org.jclouds.aws.s3.domain.AccessControlList jcACL = context.getApi().getObjectACL(
bucketName, objectKey).get(10, TimeUnit.SECONDS);
bucketName, objectKey);
assertTrue(jcACL.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
assertTrue(jcACL.hasPermission(jcACL.getOwner().getId(), Permission.FULL_CONTROL));
assertEquals(jcACL.getGrants().size(), 2);
@ -418,7 +417,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
data = "Here is some d₪t₪ for you";
requestObject.setDataInputStream(new ByteArrayInputStream(data.getBytes("UTF-8")));
jsResultObject = service.putObject(new S3Bucket(bucketName), requestObject);
jcObject = context.getApi().getObject(bucketName, objectKey).get(10, TimeUnit.SECONDS);
jcObject = context.getApi().getObject(bucketName, objectKey);
assertTrue(jsResultObject.verifyData(data.getBytes("UTF-8")));
assertEquals(jsResultObject.getETag(), jcObject.getMetadata().getETag().replaceAll("\"",
""));
@ -440,7 +439,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
String sourceMetadataValue = "souce-metadata-value";
String destinationMetadataValue = "destination-metadata-value";
Blob blob = context.getBlobStore().newBlob();
Blob blob = context.getAsyncBlobStore().newBlob();
blob.getMetadata().setName(sourceObjectKey);
blob.setData(data);
blob.getMetadata().getUserMetadata().put(metadataName, sourceMetadataValue);
@ -454,8 +453,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
destinationObject = new S3Object(destinationObjectKey);
copyResult = service.copyObject(bucketName, sourceObjectKey, bucketName,
destinationObject, false);
jcDestinationObject = context.getApi().getObject(bucketName, destinationObject.getKey())
.get(10, TimeUnit.SECONDS);
jcDestinationObject = context.getApi().getObject(bucketName, destinationObject.getKey());
// TODO null keys from s3object! assertEquals(jcDestinationObject.getKey(),
// destinationObjectKey);
assertEquals(jcDestinationObject.getMetadata().getUserMetadata().get(metadataName),
@ -463,7 +461,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
assertEquals(copyResult.get("ETag"), jcDestinationObject.getMetadata().getETag());
// Test destination ACL is unchanged (ie private)
org.jclouds.aws.s3.domain.AccessControlList jcACL = context.getApi().getObjectACL(
bucketName, destinationObject.getKey()).get(10, TimeUnit.SECONDS);
bucketName, destinationObject.getKey());
assertEquals(jcACL.getGrants().size(), 1);
assertTrue(jcACL.hasPermission(jcACL.getOwner().getId(), Permission.FULL_CONTROL));
@ -472,13 +470,11 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
destinationObject.addMetadata("x-amz-meta-" + metadataName, destinationMetadataValue);
copyResult = service.copyObject(bucketName, sourceObjectKey, bucketName,
destinationObject, true);
jcDestinationObject = context.getApi().getObject(bucketName, destinationObject.getKey())
.get(10, TimeUnit.SECONDS);
jcDestinationObject = context.getApi().getObject(bucketName, destinationObject.getKey());
assertEquals(jcDestinationObject.getMetadata().getUserMetadata().get(metadataName),
destinationMetadataValue);
// Test destination ACL is unchanged (ie private)
jcACL = context.getApi().getObjectACL(bucketName, destinationObject.getKey()).get(10,
TimeUnit.SECONDS);
jcACL = context.getApi().getObjectACL(bucketName, destinationObject.getKey());
assertEquals(jcACL.getGrants().size(), 1);
assertTrue(jcACL.hasPermission(jcACL.getOwner().getId(), Permission.FULL_CONTROL));
@ -488,8 +484,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
copyResult = service.copyObject(bucketName, sourceObjectKey, bucketName,
destinationObject, false);
// Test destination ACL is changed (ie public-read)
jcACL = context.getApi().getObjectACL(bucketName, destinationObject.getKey()).get(10,
TimeUnit.SECONDS);
jcACL = context.getApi().getObjectACL(bucketName, destinationObject.getKey());
assertEquals(jcACL.getGrants().size(), 2);
assertTrue(jcACL.hasPermission(jcACL.getOwner().getId(), Permission.FULL_CONTROL));
assertTrue(jcACL.hasPermission(GroupGranteeURI.ALL_USERS, Permission.READ));
@ -625,8 +620,8 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
}
@Test
public void testMultiService() throws InterruptedException, ExecutionException,
TimeoutException, S3ServiceException, NoSuchAlgorithmException, IOException {
public void testMultiService() throws S3ServiceException, NoSuchAlgorithmException, IOException,
InterruptedException, ExecutionException, TimeoutException {
int OBJECT_COUNT = 50;
int OBJECT_SIZE = 1024; // 1 KB
@ -668,8 +663,7 @@ public class JCloudsS3ServiceLiveTest extends BaseBlobStoreIntegrationTest<S3Cli
multiService.putObjects(bucket, objects);
assertEquals(countOfUploadCompletions[0], OBJECT_COUNT);
ListBucketResponse theBucket = context.getApi().listBucket(bucketName).get(10,
TimeUnit.SECONDS);
ListBucketResponse theBucket = context.getApi().listBucket(bucketName);
assertEquals(theBucket.size(), OBJECT_COUNT);
} finally {

View File

@ -25,7 +25,6 @@ package org.jclouds.aws.s3;
import java.io.File;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import org.jclouds.aws.s3.domain.S3Object;
@ -59,7 +58,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
S3Object object = newObject(key);
object.getMetadata().setContentType(contentType);
object.setData(data);
return context.getApi().putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
return context.getApi().putObject(bucket, object) != null;
}
@Override
@ -68,7 +67,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
S3Object object = newObject(key);
object.getMetadata().setContentType(contentType);
object.setData(data);
return context.getApi().putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
return context.getApi().putObject(bucket, object) != null;
}
private S3Object newObject(String key) {
@ -84,7 +83,7 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
object.getMetadata().setContentType(contentType);
object.setData(data);
object.setContentLength(new Long(data.available()));
return context.getApi().putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
return context.getApi().putObject(bucket, object) != null;
}
@Override
@ -93,6 +92,6 @@ public abstract class BaseJCloudsPerformanceLiveTest extends BasePerformanceLive
S3Object object = newObject(key);
object.getMetadata().setContentType(contentType);
object.setData(data);
return context.getApi().putObject(bucket, object).get(120, TimeUnit.SECONDS) != null;
return context.getApi().putObject(bucket, object) != null;
}
}

View File

@ -51,7 +51,8 @@ import org.testng.annotations.Test;
*
* @author Adrian Cole
*/
public abstract class BasePerformanceLiveTest extends BaseBlobStoreIntegrationTest<S3Client> {
public abstract class BasePerformanceLiveTest extends
BaseBlobStoreIntegrationTest<S3AsyncClient, S3Client> {
static {
containerCount = 1;
}
@ -93,8 +94,7 @@ public abstract class BasePerformanceLiveTest extends BaseBlobStoreIntegrationTe
protected String createScratchContainerInEU() throws InterruptedException, ExecutionException,
TimeoutException {
String containerName = getScratchContainerName();
context.getApi().putBucketIfNotExists(containerName, createIn(LocationConstraint.EU)).get(30,
TimeUnit.SECONDS);
context.getApi().putBucketIfNotExists(containerName, createIn(LocationConstraint.EU));
return containerName;
}

View File

@ -0,0 +1,237 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.azure.storage.blob;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.azure.storage.AzureBlob;
import org.jclouds.azure.storage.blob.binders.BindAzureBlobToEntity;
import org.jclouds.azure.storage.blob.domain.BlobProperties;
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
import org.jclouds.azure.storage.blob.functions.BlobName;
import org.jclouds.azure.storage.blob.functions.ParseBlobFromHeadersAndHttpContent;
import org.jclouds.azure.storage.blob.functions.ParseBlobPropertiesFromHeaders;
import org.jclouds.azure.storage.blob.functions.ParseContainerPropertiesFromHeaders;
import org.jclouds.azure.storage.blob.functions.ReturnTrueIfContainerAlreadyExists;
import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
import org.jclouds.azure.storage.blob.xml.AccountNameEnumerationResultsHandler;
import org.jclouds.azure.storage.blob.xml.ContainerNameEnumerationResultsHandler;
import org.jclouds.azure.storage.domain.BoundedSortedSet;
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.attr.ConsistencyModels;
import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ParseETagHeader;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.http.functions.ReturnTrueOn404;
import org.jclouds.http.options.GetOptions;
import org.jclouds.rest.annotations.BinderParam;
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.annotations.XMLResponseParser;
/**
* Provides asynchronous access to Azure Blob via their REST API.
* <p/>
* All commands return a Future of the result from Azure Blob. Any exceptions incurred during
* processing will be wrapped in an {@link ExecutionException} as documented in {@link Future#get()}.
*
* @see <a href="http://msdn.microsoft.com/en-us/library/dd135733.aspx" />
* @see AzureBlobClient
* @author Adrian Cole
*/
@SkipEncoding('/')
@RequestFilters(SharedKeyAuthentication.class)
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-07-17")
@Endpoint(AzureBlob.class)
@ConsistencyModel(ConsistencyModels.STRICT)
public interface AzureBlobAsyncClient {
public org.jclouds.azure.storage.blob.domain.AzureBlob newBlob();
/**
* @see AzureBlobClient#listContainers
*/
@GET
@XMLResponseParser(AccountNameEnumerationResultsHandler.class)
@Path("/")
@QueryParams(keys = "comp", values = "list")
Future<? extends BoundedSortedSet<ListableContainerProperties>> listContainers(
ListOptions... listOptions);
/**
* @see AzureBlobClient#createContainer
*/
@PUT
@Path("{container}")
@ExceptionParser(ReturnTrueIfContainerAlreadyExists.class)
@QueryParams(keys = "restype", values = "container")
Future<Boolean> createContainer(@PathParam("container") String container,
CreateContainerOptions... options);
/**
* @see AzureBlobClient#getContainerProperties
*/
@HEAD
@Path("{container}")
@QueryParams(keys = "restype", values = "container")
@ResponseParser(ParseContainerPropertiesFromHeaders.class)
Future<ListableContainerProperties> getContainerProperties(
@PathParam("container") String container);
/**
* @see AzureBlobClient#containerExists
*/
@HEAD
@Path("{container}")
@QueryParams(keys = "restype", values = "container")
@ExceptionParser(ReturnFalseOn404.class)
Future<Boolean> containerExists(@PathParam("container") String container);
/**
* @see AzureBlobClient#setResourceMetadata
*/
@PUT
@Path("{container}")
@QueryParams(keys = { "restype", "comp" }, values = { "container", "metadata" })
Future<Void> setResourceMetadata(@PathParam("container") String container,
@BinderParam(BindMapToHeadersWithPrefix.class) Map<String, String> metadata);
/**
* @see AzureBlobClient#deleteContainer
*/
@DELETE
@Path("{container}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@QueryParams(keys = "restype", values = "container")
Future<Void> deleteContainer(@PathParam("container") String container);
/**
* @see AzureBlobClient#createRootContainer
*/
@PUT
@Path("$root")
@ExceptionParser(ReturnTrueIfContainerAlreadyExists.class)
@QueryParams(keys = "restype", values = "container")
Future<Boolean> createRootContainer(CreateContainerOptions... options);
/**
* @see AzureBlobClient#deleteRootContainer
*/
@DELETE
@Path("$root")
@ExceptionParser(ReturnTrueOn404.class)
@QueryParams(keys = "restype", values = "container")
Future<Boolean> deleteRootContainer();
/**
* @see AzureBlobClient#listBlobs(String, ListBlobsOptions)
*/
@GET
@XMLResponseParser(ContainerNameEnumerationResultsHandler.class)
@Path("{container}")
@QueryParams(keys = { "restype", "comp" }, values = { "container", "list" })
Future<ListBlobsResponse> listBlobs(@PathParam("container") String container,
ListBlobsOptions... options);
/**
* @see AzureBlobClient#listBlobs(ListBlobsOptions)
*/
@GET
@XMLResponseParser(ContainerNameEnumerationResultsHandler.class)
@Path("$root")
@QueryParams(keys = { "restype", "comp" }, values = { "container", "list" })
Future<ListBlobsResponse> listBlobs(ListBlobsOptions... options);
/**
* @see AzureBlobClient#putBlob
*/
@PUT
@Path("{container}/{name}")
@ResponseParser(ParseETagHeader.class)
Future<String> putBlob(
@PathParam("container") String container,
@PathParam("name") @ParamParser(BlobName.class) @BinderParam(BindAzureBlobToEntity.class) org.jclouds.azure.storage.blob.domain.AzureBlob object);
/**
* @see AzureBlobClient#getBlob
*/
@GET
@ResponseParser(ParseBlobFromHeadersAndHttpContent.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("{container}/{name}")
Future<org.jclouds.azure.storage.blob.domain.AzureBlob> getBlob(
@PathParam("container") String container, @PathParam("name") String name,
GetOptions... options);
/**
* @see AzureBlobClient#getBlobProperties
*/
@HEAD
@ResponseParser(ParseBlobPropertiesFromHeaders.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("{container}/{name}")
Future<BlobProperties> getBlobProperties(@PathParam("container") String container,
@PathParam("name") String name);
/**
* @see AzureBlobClient#setBlobMetadata
*/
@PUT
@Path("{container}/{name}")
@QueryParams(keys = { "comp" }, values = { "metadata" })
Future<Void> setBlobMetadata(@PathParam("container") String container,
@PathParam("name") String name,
@BinderParam(BindMapToHeadersWithPrefix.class) Map<String, String> metadata);
/**
* @see AzureBlobClient#deleteBlob
*/
@DELETE
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Path("{container}/{name}")
Future<Void> deleteBlob(@PathParam("container") String container, @PathParam("name") String name);
}

View File

@ -26,49 +26,17 @@ package org.jclouds.azure.storage.blob;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.azure.storage.AzureBlob;
import org.jclouds.azure.storage.blob.binders.BindAzureBlobToEntity;
import org.jclouds.azure.storage.blob.domain.BlobProperties;
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
import org.jclouds.azure.storage.blob.functions.BlobName;
import org.jclouds.azure.storage.blob.functions.ParseBlobFromHeadersAndHttpContent;
import org.jclouds.azure.storage.blob.functions.ParseBlobPropertiesFromHeaders;
import org.jclouds.azure.storage.blob.functions.ParseContainerPropertiesFromHeaders;
import org.jclouds.azure.storage.blob.functions.ReturnTrueIfContainerAlreadyExists;
import org.jclouds.azure.storage.blob.options.CreateContainerOptions;
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
import org.jclouds.azure.storage.blob.xml.AccountNameEnumerationResultsHandler;
import org.jclouds.azure.storage.blob.xml.ContainerNameEnumerationResultsHandler;
import org.jclouds.azure.storage.domain.BoundedSortedSet;
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
import org.jclouds.blobstore.binders.BindMapToHeadersWithPrefix;
import org.jclouds.blobstore.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404;
import org.jclouds.http.functions.ParseETagHeader;
import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.http.functions.ReturnTrueOn404;
import org.jclouds.concurrent.Timeout;
import org.jclouds.http.options.GetOptions;
import org.jclouds.rest.annotations.BinderParam;
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.annotations.XMLResponseParser;
/**
* Provides access to Azure Blob via their REST API.
@ -79,10 +47,7 @@ import org.jclouds.rest.annotations.XMLResponseParser;
* @see <a href="http://msdn.microsoft.com/en-us/library/dd135733.aspx" />
* @author Adrian Cole
*/
@SkipEncoding('/')
@RequestFilters(SharedKeyAuthentication.class)
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-07-17")
@Endpoint(AzureBlob.class)
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface AzureBlobClient {
public org.jclouds.azure.storage.blob.domain.AzureBlob newBlob();
@ -95,12 +60,7 @@ public interface AzureBlobClient {
* controls the number or type of results requested
* @see ListOptions
*/
@GET
@XMLResponseParser(AccountNameEnumerationResultsHandler.class)
@Path("/")
@QueryParams(keys = "comp", values = "list")
Future<? extends BoundedSortedSet<ListableContainerProperties>> listContainers(
ListOptions... listOptions);
BoundedSortedSet<ListableContainerProperties> listContainers(ListOptions... listOptions);
/**
* The Create Container operation creates a new container under the specified account. If the
@ -112,31 +72,18 @@ public interface AzureBlobClient {
* @see CreateContainerOptions
*
*/
@PUT
@Path("{container}")
@ExceptionParser(ReturnTrueIfContainerAlreadyExists.class)
@QueryParams(keys = "restype", values = "container")
Future<Boolean> createContainer(@PathParam("container") String container,
CreateContainerOptions... options);
boolean createContainer(String container, CreateContainerOptions... options);
/**
* The Get Container Properties operation returns all user-defined metadata and system properties
* for the specified container. The data returned does not include the container's list of blobs.
*/
@HEAD
@Path("{container}")
@QueryParams(keys = "restype", values = "container")
@ResponseParser(ParseContainerPropertiesFromHeaders.class)
ListableContainerProperties getContainerProperties(@PathParam("container") String container);
ListableContainerProperties getContainerProperties(String container);
/**
* Issues a HEAD command to determine if the container exists or not.
*/
@HEAD
@Path("{container}")
@QueryParams(keys = "restype", values = "container")
@ExceptionParser(ReturnFalseOn404.class)
boolean containerExists(@PathParam("container") String container);
boolean containerExists(String container);
/**
* The Set Container Metadata operation sets one or more user-defined name/value pairs for the
@ -150,11 +97,7 @@ public interface AzureBlobClient {
* <p/>
* Calling Set Container Metadata updates the ETag for the container.
*/
@PUT
@Path("{container}")
@QueryParams(keys = { "restype", "comp" }, values = { "container", "metadata" })
void setResourceMetadata(@PathParam("container") String container,
@BinderParam(BindMapToHeadersWithPrefix.class) Map<String, String> metadata);
void setResourceMetadata(String container, Map<String, String> metadata);
/**
* The Delete Container operation marks the specified container for deletion. The container and
@ -169,11 +112,7 @@ public interface AzureBlobClient {
* 404 (Not Found) while the container is being deleted.
*
*/
@DELETE
@Path("{container}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@QueryParams(keys = "restype", values = "container")
Future<Void> deleteContainer(@PathParam("container") String container);
void deleteContainer(String container);
/**
* The root container is a default container that may be inferred from a URL requesting a blob
@ -186,11 +125,7 @@ public interface AzureBlobClient {
* @see CreateContainerOptions
*
*/
@PUT
@Path("$root")
@ExceptionParser(ReturnTrueIfContainerAlreadyExists.class)
@QueryParams(keys = "restype", values = "container")
Future<Boolean> createRootContainer(CreateContainerOptions... options);
boolean createRootContainer(CreateContainerOptions... options);
/**
* The Delete Container operation marks the specified container for deletion. The container and
@ -206,11 +141,7 @@ public interface AzureBlobClient {
* @see deleteContainer(String)
* @see createRootContainer(CreateContainerOptions)
*/
@DELETE
@Path("$root")
@ExceptionParser(ReturnTrueOn404.class)
@QueryParams(keys = "restype", values = "container")
Future<Boolean> deleteRootContainer();
boolean deleteRootContainer();
/**
* The List Blobs operation enumerates the list of blobs under the specified container.
@ -247,18 +178,9 @@ public interface AzureBlobClient {
* <p/>
* Blobs are listed in alphabetical order in the response body.
*/
@GET
@XMLResponseParser(ContainerNameEnumerationResultsHandler.class)
@Path("{container}")
@QueryParams(keys = { "restype", "comp" }, values = { "container", "list" })
Future<ListBlobsResponse> listBlobs(@PathParam("container") String container,
ListBlobsOptions... options);
ListBlobsResponse listBlobs(String container, ListBlobsOptions... options);
@GET
@XMLResponseParser(ContainerNameEnumerationResultsHandler.class)
@Path("$root")
@QueryParams(keys = { "restype", "comp" }, values = { "container", "list" })
Future<ListBlobsResponse> listBlobs(ListBlobsOptions... options);
ListBlobsResponse listBlobs(ListBlobsOptions... options);
/**
* The Put Blob operation creates a new blob or updates the content of an existing blob.
@ -278,49 +200,27 @@ public interface AzureBlobClient {
* A Put Blob operation is permitted 10 minutes per MB to complete. If the operation is taking
* longer than 10 minutes per MB on average, the operation will timeout.
*/
@PUT
@Path("{container}/{name}")
@ResponseParser(ParseETagHeader.class)
Future<String> putBlob(
@PathParam("container") String container,
@PathParam("name") @ParamParser(BlobName.class) @BinderParam(BindAzureBlobToEntity.class) org.jclouds.azure.storage.blob.domain.AzureBlob object);
String putBlob(String container, org.jclouds.azure.storage.blob.domain.AzureBlob object);
/**
* The Get Blob operation reads or downloads a blob from the system, including its metadata and
* properties.
*/
@GET
@ResponseParser(ParseBlobFromHeadersAndHttpContent.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("{container}/{name}")
Future<org.jclouds.azure.storage.blob.domain.AzureBlob> getBlob(
@PathParam("container") String container, @PathParam("name") String name,
org.jclouds.azure.storage.blob.domain.AzureBlob getBlob(String container, String name,
GetOptions... options);
/**
* The Get Blob Properties operation returns all user-defined metadata, standard HTTP properties,
* and system properties for the blob. It does not return the content of the blob.
*/
@HEAD
@ResponseParser(ParseBlobPropertiesFromHeaders.class)
@ExceptionParser(ThrowKeyNotFoundOn404.class)
@Path("{container}/{name}")
BlobProperties getBlobProperties(@PathParam("container") String container,
@PathParam("name") String name);
@PUT
@Path("{container}/{name}")
@QueryParams(keys = { "comp" }, values = { "metadata" })
void setBlobMetadata(@PathParam("container") String container, @PathParam("name") String name,
@BinderParam(BindMapToHeadersWithPrefix.class) Map<String, String> metadata);
BlobProperties getBlobProperties(String container, String name);
void setBlobMetadata(String container, String name, Map<String, String> metadata);
/**
* The Delete Blob operation marks the specified blob for deletion. The blob is later deleted
* during garbage collection.
*/
@DELETE
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Path("{container}/{name}")
Future<Void> deleteBlob(@PathParam("container") String container, @PathParam("name") String name);
void deleteBlob(String container, String name);
}

View File

@ -48,14 +48,15 @@ import com.google.inject.TypeLiteral;
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see AzureBlobClient
* @see AzureBlobAsyncClient
*/
public class AzureBlobContextBuilder extends RestContextBuilder<AzureBlobClient> {
private static final TypeLiteral<AzureBlobClient> connectionType = new TypeLiteral<AzureBlobClient>() {
};
public class AzureBlobContextBuilder extends
RestContextBuilder<AzureBlobAsyncClient, AzureBlobClient> {
public AzureBlobContextBuilder(Properties properties) {
super(connectionType, properties);
super(new TypeLiteral<AzureBlobAsyncClient>() {
}, new TypeLiteral<AzureBlobClient>() {
}, properties);
}
@Override

View File

@ -42,24 +42,24 @@ import com.google.inject.Module;
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see AzureBlobClient
* @see AzureBlobAsyncClient
*/
public class AzureBlobContextFactory {
public static RestContext<AzureBlobClient> createContext(Properties properties,
Module... modules) {
public static RestContext<AzureBlobAsyncClient, AzureBlobClient> createContext(
Properties properties, Module... modules) {
return new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder(properties).build())
.withModules(modules).buildContext();
}
public static RestContext<AzureBlobClient> createContext(String account, String encodedKey,
Module... modules) {
public static RestContext<AzureBlobAsyncClient, AzureBlobClient> createContext(String account,
String encodedKey, Module... modules) {
return new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder(account, encodedKey)
.build()).withModules(modules).buildContext();
}
public static RestContext<AzureBlobClient> createContext(URI endpoint, String account,
String encodedKey, Module... modules) {
public static RestContext<AzureBlobAsyncClient, AzureBlobClient> createContext(URI endpoint,
String account, String encodedKey, Module... modules) {
return new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder(account, encodedKey)
.withEndpoint(endpoint).build()).withModules(modules).buildContext();
}

View File

@ -0,0 +1,154 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.azure.storage.blob.blobstore;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import java.util.SortedSet;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.inject.Inject;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.blobstore.functions.AzureBlobToBlob;
import org.jclouds.azure.storage.blob.blobstore.functions.BlobPropertiesToBlobMetadata;
import org.jclouds.azure.storage.blob.blobstore.functions.BlobToAzureBlob;
import org.jclouds.azure.storage.blob.blobstore.functions.ContainerToResourceMetadata;
import org.jclouds.azure.storage.blob.blobstore.functions.ListBlobsResponseToResourceList;
import org.jclouds.azure.storage.blob.blobstore.functions.ListOptionsToListBlobsOptions;
import org.jclouds.azure.storage.blob.blobstore.internal.BaseAzureBlobStore;
import org.jclouds.azure.storage.blob.domain.AzureBlob;
import org.jclouds.azure.storage.blob.domain.BlobProperties;
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
public class AzureAsyncBlobStore extends BaseAzureBlobStore implements AsyncBlobStore {
@Inject
public AzureAsyncBlobStore(AzureBlobAsyncClient async, AzureBlobClient sync,
Factory blobFactory, LoggerFactory logFactory,
ClearListStrategy clearContainerStrategy, BlobPropertiesToBlobMetadata object2BlobMd,
AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object,
ListOptionsToListBlobsOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions,
ContainerToResourceMetadata container2ResourceMd,
ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) {
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions,
container2ResourceMd, container2ResourceList, service);
}
/**
* This implementation uses the AzureBlob HEAD Object command to return the result
*/
public Future<BlobMetadata> blobMetadata(String container, String key) {
return wrapFuture(async.getBlobProperties(container, key),
new Function<BlobProperties, BlobMetadata>() {
@Override
public BlobMetadata apply(BlobProperties from) {
return object2BlobMd.apply(from);
}
});
}
public Future<Void> clearContainer(final String container) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
return null;
}
});
}
public Future<Boolean> createContainer(String container) {
return async.createContainer(container);
}
public Future<Void> deleteContainer(final String container) {
return async.deleteContainer(container);
}
public Future<Boolean> exists(String container) {
return async.containerExists(container);
}
public Future<Blob> getBlob(String container, String key,
org.jclouds.blobstore.options.GetOptions... optionsList) {
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
Future<AzureBlob> returnVal = async.getBlob(container, key, httpOptions);
return wrapFuture(returnVal, object2Blob);
}
public Future<? extends org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>> list() {
return wrapFuture(
async.listContainers(),
new Function<SortedSet<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
SortedSet<ListableContainerProperties> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
container2ResourceMd), null, null, false);
}
});
}
public Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(
String container, ListContainerOptions... optionsList) {
ListBlobsOptions httpOptions = container2ContainerListOptions.apply(optionsList);
Future<ListBlobsResponse> returnVal = async.listBlobs(container, httpOptions);
return wrapFuture(returnVal, container2ResourceList);
}
public Future<String> putBlob(String container, Blob blob) {
return async.putBlob(container, blob2Object.apply(blob));
}
public Future<Void> removeBlob(String container, String key) {
return async.deleteBlob(container, key);
}
}

View File

@ -23,16 +23,14 @@
*/
package org.jclouds.azure.storage.blob.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import java.util.SortedSet;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.inject.Inject;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.blobstore.functions.AzureBlobToBlob;
import org.jclouds.azure.storage.blob.blobstore.functions.BlobPropertiesToBlobMetadata;
@ -40,45 +38,30 @@ import org.jclouds.azure.storage.blob.blobstore.functions.BlobToAzureBlob;
import org.jclouds.azure.storage.blob.blobstore.functions.ContainerToResourceMetadata;
import org.jclouds.azure.storage.blob.blobstore.functions.ListBlobsResponseToResourceList;
import org.jclouds.azure.storage.blob.blobstore.functions.ListOptionsToListBlobsOptions;
import org.jclouds.azure.storage.blob.domain.AzureBlob;
import org.jclouds.azure.storage.blob.domain.ListBlobsResponse;
import org.jclouds.azure.storage.blob.blobstore.internal.BaseAzureBlobStore;
import org.jclouds.azure.storage.blob.domain.ListableContainerProperties;
import org.jclouds.azure.storage.blob.options.ListBlobsOptions;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.attr.ConsistencyModels;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.domain.BlobMetadata;
import org.jclouds.blobstore.domain.ListContainerResponse;
import org.jclouds.blobstore.domain.ListResponse;
import org.jclouds.blobstore.domain.ResourceMetadata;
import org.jclouds.blobstore.domain.Blob.Factory;
import org.jclouds.blobstore.domain.internal.ListResponseImpl;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.http.options.GetOptions;
import org.jclouds.logging.Logger.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
@ConsistencyModel(ConsistencyModels.STRICT)
public class AzureBlobStore implements BlobStore {
private final AzureBlobClient connection;
private final Blob.Factory blobFactory;
private final LoggerFactory logFactory;
private final ClearListStrategy clearContainerStrategy;
private final BlobPropertiesToBlobMetadata object2BlobMd;
private final AzureBlobToBlob object2Blob;
private final BlobToAzureBlob blob2Object;
private final ListOptionsToListBlobsOptions container2ContainerListOptions;
private final BlobToHttpGetOptions blob2ObjectGetOptions;
private final ContainerToResourceMetadata container2ResourceMd;
private final ListBlobsResponseToResourceList container2ResourceList;
private final ExecutorService service;
public class AzureBlobStore extends BaseAzureBlobStore implements BlobStore {
@Inject
private AzureBlobStore(AzureBlobClient connection, Blob.Factory blobFactory,
public AzureBlobStore(AzureBlobAsyncClient async, AzureBlobClient sync, Factory blobFactory,
LoggerFactory logFactory, ClearListStrategy clearContainerStrategy,
BlobPropertiesToBlobMetadata object2BlobMd, AzureBlobToBlob object2Blob,
BlobToAzureBlob blob2Object,
@ -86,93 +69,62 @@ public class AzureBlobStore implements BlobStore {
BlobToHttpGetOptions blob2ObjectGetOptions,
ContainerToResourceMetadata container2ResourceMd,
ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) {
this.connection = checkNotNull(connection, "connection");
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
this.logFactory = checkNotNull(logFactory, "logFactory");
this.clearContainerStrategy = checkNotNull(clearContainerStrategy, "clearContainerStrategy");
this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd");
this.object2Blob = checkNotNull(object2Blob, "object2Blob");
this.blob2Object = checkNotNull(blob2Object, "blob2Object");
this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions,
"container2ContainerListOptions");
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
this.container2ResourceMd = checkNotNull(container2ResourceMd, "container2ResourceMd");
this.container2ResourceList = checkNotNull(container2ResourceList, "container2ResourceList");
this.service = checkNotNull(service, "service");
}
protected <F, T> Future<T> wrapFuture(Future<? extends F> future, Function<F, T> function) {
return new FutureFunctionWrapper<F, T>(future, function, logFactory.getLogger(function
.getClass().getName()));
super(async, sync, blobFactory, logFactory, clearContainerStrategy, object2BlobMd,
object2Blob, blob2Object, container2ContainerListOptions, blob2ObjectGetOptions,
container2ResourceMd, container2ResourceList, service);
}
/**
* This implementation uses the AzureBlob HEAD Object command to return the result
*/
public BlobMetadata blobMetadata(String container, String key) {
return object2BlobMd.apply(connection.getBlobProperties(container, key));
return object2BlobMd.apply(sync.getBlobProperties(container, key));
}
public Future<Void> clearContainer(final String container) {
return service.submit(new Callable<Void>() {
public Void call() throws Exception {
clearContainerStrategy.execute(container, recursive());
return null;
}
});
public void clearContainer(final String container) {
clearContainerStrategy.execute(container, recursive());
}
public Future<Boolean> createContainer(String container) {
return connection.createContainer(container);
public boolean createContainer(String container) {
return sync.createContainer(container);
}
public Future<Void> deleteContainer(final String container) {
return connection.deleteContainer(container);
public void deleteContainer(final String container) {
sync.deleteContainer(container);
}
public boolean exists(String container) {
return connection.containerExists(container);
return sync.containerExists(container);
}
public Future<Blob> getBlob(String container, String key,
public Blob getBlob(String container, String key,
org.jclouds.blobstore.options.GetOptions... optionsList) {
GetOptions httpOptions = blob2ObjectGetOptions.apply(optionsList);
Future<AzureBlob> returnVal = connection.getBlob(container, key, httpOptions);
return wrapFuture(returnVal, object2Blob);
return object2Blob.apply(sync.getBlob(container, key, httpOptions));
}
public Future<? extends org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>> list() {
return wrapFuture(
connection.listContainers(),
new Function<SortedSet<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
SortedSet<ListableContainerProperties> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
container2ResourceMd), null, null, false);
}
});
public ListResponse<? extends ResourceMetadata> list() {
return new Function<SortedSet<ListableContainerProperties>, org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata>>() {
public org.jclouds.blobstore.domain.ListResponse<? extends ResourceMetadata> apply(
SortedSet<ListableContainerProperties> from) {
return new ListResponseImpl<ResourceMetadata>(Iterables.transform(from,
container2ResourceMd), null, null, false);
}
}.apply(sync.listContainers());
}
public Future<? extends ListContainerResponse<? extends ResourceMetadata>> list(String container,
public ListContainerResponse<? extends ResourceMetadata> list(String container,
ListContainerOptions... optionsList) {
ListBlobsOptions httpOptions = container2ContainerListOptions.apply(optionsList);
Future<ListBlobsResponse> returnVal = connection.listBlobs(container, httpOptions);
return wrapFuture(returnVal, container2ResourceList);
return container2ResourceList.apply(sync.listBlobs(container, httpOptions));
}
public Future<String> putBlob(String container, Blob blob) {
return connection.putBlob(container, blob2Object.apply(blob));
public String putBlob(String container, Blob blob) {
return sync.putBlob(container, blob2Object.apply(blob));
}
public Future<Void> removeBlob(String container, String key) {
return connection.deleteBlob(container, key);
}
public Blob newBlob() {
return blobFactory.create(null);
public void removeBlob(String container, String key) {
sync.deleteBlob(container, key);
}
}

View File

@ -34,6 +34,7 @@ import java.util.Properties;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.blobstore.config.AzureBlobStoreContextModule;
import org.jclouds.azure.storage.blob.config.AzureBlobRestClientModule;
@ -59,10 +60,12 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole, Andrew Newdigate
* @see AzureBlobStoreContext
*/
public class AzureBlobStoreContextBuilder extends BlobStoreContextBuilder<AzureBlobClient> {
public class AzureBlobStoreContextBuilder extends
BlobStoreContextBuilder<AzureBlobAsyncClient, AzureBlobClient> {
public AzureBlobStoreContextBuilder(Properties props) {
super(new TypeLiteral<AzureBlobClient>() {
super(new TypeLiteral<AzureBlobAsyncClient>() {
}, new TypeLiteral<AzureBlobClient>() {
}, convert(props));
}

View File

@ -26,6 +26,7 @@ package org.jclouds.azure.storage.blob.blobstore;
import java.net.URI;
import java.util.Properties;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.AzureBlobPropertiesBuilder;
import org.jclouds.blobstore.BlobStoreContext;
@ -47,20 +48,20 @@ import com.google.inject.Module;
* @see AzureBlobStoreContext
*/
public class AzureBlobStoreContextFactory {
public static BlobStoreContext<AzureBlobClient> createContext(Properties properties,
Module... modules) {
public static BlobStoreContext<AzureBlobAsyncClient, AzureBlobClient> createContext(
Properties properties, Module... modules) {
return new AzureBlobStoreContextBuilder(new AzureBlobPropertiesBuilder(properties).build())
.withModules(modules).buildContext();
}
public static BlobStoreContext<AzureBlobClient> createContext(String user, String encodedKey,
Module... modules) {
public static BlobStoreContext<AzureBlobAsyncClient, AzureBlobClient> createContext(String user,
String encodedKey, Module... modules) {
return new AzureBlobStoreContextBuilder(new AzureBlobPropertiesBuilder(user, encodedKey)
.build()).withModules(modules).buildContext();
}
public static BlobStoreContext<AzureBlobClient> createContext(URI endpoint, String user,
String encodedKey, Module... modules) {
public static BlobStoreContext<AzureBlobAsyncClient, AzureBlobClient> createContext(
URI endpoint, String user, String encodedKey, Module... modules) {
return new AzureBlobStoreContextBuilder(new AzureBlobPropertiesBuilder(user, encodedKey)
.withEndpoint(endpoint).build()).withModules(modules).buildContext();
}

View File

@ -29,11 +29,14 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.azure.storage.AzureBlob;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.blobstore.AzureAsyncBlobStore;
import org.jclouds.azure.storage.blob.blobstore.AzureBlobStore;
import org.jclouds.azure.storage.blob.blobstore.strategy.FindMD5InBlobProperties;
import org.jclouds.azure.storage.blob.config.AzureBlobModule;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.blobstore.AsyncBlobStore;
import org.jclouds.blobstore.BlobMap;
import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.BlobStoreContext;
@ -48,7 +51,7 @@ import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* Configures the {@link AzureBlobStoreContext}; requires {@link AzureBlobStore} bound.
* Configures the {@link AzureBlobStoreContext}; requires {@link AzureAsyncBlobStore} bound.
*
* @author Adrian Cole
*/
@ -59,18 +62,21 @@ public class AzureBlobStoreContextModule extends AbstractModule {
install(new BlobStoreObjectModule());
install(new BlobStoreMapModule());
install(new AzureBlobModule());
bind(AsyncBlobStore.class).to(AzureAsyncBlobStore.class).asEagerSingleton();
bind(BlobStore.class).to(AzureBlobStore.class).asEagerSingleton();
bind(ContainsValueInListStrategy.class).to(FindMD5InBlobProperties.class);
}
@Provides
@Singleton
BlobStoreContext<AzureBlobClient> provideContext(BlobMap.Factory blobMapFactory,
InputStreamMap.Factory inputStreamMapFactory, Closer closer, BlobStore blobStore,
AzureBlobClient defaultApi, @AzureBlob URI endPoint,
BlobStoreContext<AzureBlobAsyncClient, AzureBlobClient> provideContext(
BlobMap.Factory blobMapFactory, InputStreamMap.Factory inputStreamMapFactory,
Closer closer, AsyncBlobStore asyncBlobStore, BlobStore blobStore,
AzureBlobAsyncClient asyncApi, AzureBlobClient defaultApi, @AzureBlob URI endPoint,
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account) {
return new BlobStoreContextImpl<AzureBlobClient>(blobMapFactory, inputStreamMapFactory,
closer, blobStore, defaultApi, endPoint, account);
return new BlobStoreContextImpl<AzureBlobAsyncClient, AzureBlobClient>(blobMapFactory,
inputStreamMapFactory, closer, asyncBlobStore, blobStore, asyncApi, defaultApi,
endPoint, account);
}
}

View File

@ -0,0 +1,98 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.azure.storage.blob.blobstore.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.inject.Inject;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.blobstore.functions.AzureBlobToBlob;
import org.jclouds.azure.storage.blob.blobstore.functions.BlobPropertiesToBlobMetadata;
import org.jclouds.azure.storage.blob.blobstore.functions.BlobToAzureBlob;
import org.jclouds.azure.storage.blob.blobstore.functions.ContainerToResourceMetadata;
import org.jclouds.azure.storage.blob.blobstore.functions.ListBlobsResponseToResourceList;
import org.jclouds.azure.storage.blob.blobstore.functions.ListOptionsToListBlobsOptions;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.strategy.ClearListStrategy;
import org.jclouds.concurrent.FutureFunctionWrapper;
import org.jclouds.logging.Logger.LoggerFactory;
import com.google.common.base.Function;
public class BaseAzureBlobStore {
protected final AzureBlobAsyncClient async;
protected final AzureBlobClient sync;
protected final Blob.Factory blobFactory;
protected final LoggerFactory logFactory;
protected final ClearListStrategy clearContainerStrategy;
protected final BlobPropertiesToBlobMetadata object2BlobMd;
protected final AzureBlobToBlob object2Blob;
protected final BlobToAzureBlob blob2Object;
protected final ListOptionsToListBlobsOptions container2ContainerListOptions;
protected final BlobToHttpGetOptions blob2ObjectGetOptions;
protected final ContainerToResourceMetadata container2ResourceMd;
protected final ListBlobsResponseToResourceList container2ResourceList;
protected final ExecutorService service;
@Inject
protected BaseAzureBlobStore(AzureBlobAsyncClient async, AzureBlobClient sync,
Blob.Factory blobFactory, LoggerFactory logFactory,
ClearListStrategy clearContainerStrategy, BlobPropertiesToBlobMetadata object2BlobMd,
AzureBlobToBlob object2Blob, BlobToAzureBlob blob2Object,
ListOptionsToListBlobsOptions container2ContainerListOptions,
BlobToHttpGetOptions blob2ObjectGetOptions,
ContainerToResourceMetadata container2ResourceMd,
ListBlobsResponseToResourceList container2ResourceList, ExecutorService service) {
this.async = checkNotNull(async, "async");
this.sync = checkNotNull(sync, "sync");
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
this.logFactory = checkNotNull(logFactory, "logFactory");
this.clearContainerStrategy = checkNotNull(clearContainerStrategy, "clearContainerStrategy");
this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd");
this.object2Blob = checkNotNull(object2Blob, "object2Blob");
this.blob2Object = checkNotNull(blob2Object, "blob2Object");
this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions,
"container2ContainerListOptions");
this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
this.container2ResourceMd = checkNotNull(container2ResourceMd, "container2ResourceMd");
this.container2ResourceList = checkNotNull(container2ResourceList, "container2ResourceList");
this.service = checkNotNull(service, "service");
}
protected <F, T> Future<T> wrapFuture(Future<? extends F> future, Function<F, T> function) {
return new FutureFunctionWrapper<F, T>(future, function, logFactory.getLogger(function
.getClass().getName()));
}
public Blob newBlob() {
return blobFactory.create(null);
}
}

View File

@ -29,6 +29,7 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.azure.storage.AzureBlob;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.blobstore.config.BlobStoreObjectModule;
@ -52,10 +53,11 @@ public class AzureBlobContextModule extends AbstractModule {
@Provides
@Singleton
RestContext<AzureBlobClient> provideContext(Closer closer, AzureBlobClient defaultApi,
@AzureBlob URI endPoint,
RestContext<AzureBlobAsyncClient, AzureBlobClient> provideContext(Closer closer,
AzureBlobAsyncClient asyncApi, AzureBlobClient defaultApi, @AzureBlob URI endPoint,
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account) {
return new RestContextImpl<AzureBlobClient>(closer, defaultApi, endPoint, account);
return new RestContextImpl<AzureBlobAsyncClient, AzureBlobClient>(closer, asyncApi,
defaultApi, endPoint, account);
}
}

View File

@ -29,10 +29,12 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.azure.storage.AzureBlob;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.handlers.AzureBlobClientErrorRetryHandler;
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
import org.jclouds.azure.storage.config.AzureStorageRestClientModule;
import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
@ -60,8 +62,15 @@ public class AzureBlobRestClientModule extends AzureStorageRestClientModule {
@Provides
@Singleton
protected AzureBlobClient provideAzureStorageClient(RestClientFactory factory) {
return factory.create(AzureBlobClient.class);
protected AzureBlobAsyncClient provideAsyncClient(RestClientFactory factory) {
return factory.create(AzureBlobAsyncClient.class);
}
@Provides
@Singleton
public AzureBlobClient provideClient(AzureBlobAsyncClient client)
throws IllegalArgumentException, SecurityException, NoSuchMethodException {
return SyncProxy.create(AzureBlobClient.class, client);
}
@Override

View File

@ -0,0 +1,100 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.azure.storage.queue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.azure.storage.AzureQueue;
import org.jclouds.azure.storage.domain.BoundedSortedSet;
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
import org.jclouds.azure.storage.options.CreateOptions;
import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
import org.jclouds.azure.storage.queue.xml.AccountNameEnumerationResultsHandler;
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.annotations.XMLResponseParser;
/**
* Provides asynchronous access to Azure Queue via their REST API.
* <p/>
* The Queue service stores messages that may be read by any client who has access to the storage
* account.
* <p/>
* A queue can contain an unlimited number of messages, each of which can be up to 8 KB in size.
* Messages are generally added to the end of the queue and retrieved from the front of the queue,
* although first in, first out (FIFO) behavior is not guaranteed.
* <p/>
* If you need to store messages larger than 8 KB, you can store message data as a blob or in a
* table, and then store a reference to the data as a message in a queue.
* <p/>
* All commands return a Future of the result from Azure Queue. Any exceptions incurred during
* processing will be wrapped in an {@link ExecutionException} as documented in {@link Future#get()}.
*
* @see <a href="http://msdn.microsoft.com/en-us/library/dd135733.aspx" />
* @author Adrian Cole
*/
@SkipEncoding('/')
@RequestFilters(SharedKeyAuthentication.class)
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-07-17")
@Endpoint(AzureQueue.class)
public interface AzureQueueAsyncClient {
/**
* @see AzureQueueClient#listQueues
*/
@GET
@XMLResponseParser(AccountNameEnumerationResultsHandler.class)
@Path("/")
@QueryParams(keys = "comp", values = "list")
Future<? extends BoundedSortedSet<QueueMetadata>> listQueues(ListOptions... listOptions);
/**
* @see AzureQueueClient#createQueue
*/
@PUT
@Path("{queue}")
@QueryParams(keys = "restype", values = "queue")
Future<Boolean> createQueue(@PathParam("queue") String queue, CreateOptions... options);
/**
* @see AzureQueueClient#deleteQueue
*/
@DELETE
@Path("{queue}")
@QueryParams(keys = "restype", values = "queue")
Future<Boolean> deleteQueue(@PathParam("queue") String queue);
}

View File

@ -25,27 +25,15 @@ package org.jclouds.azure.storage.queue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.azure.storage.AzureQueue;
import org.jclouds.azure.storage.domain.BoundedSortedSet;
import org.jclouds.azure.storage.filters.SharedKeyAuthentication;
import org.jclouds.azure.storage.options.CreateOptions;
import org.jclouds.azure.storage.options.ListOptions;
import org.jclouds.azure.storage.queue.domain.QueueMetadata;
import org.jclouds.azure.storage.queue.xml.AccountNameEnumerationResultsHandler;
import org.jclouds.azure.storage.reference.AzureStorageHeaders;
import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.concurrent.Timeout;
/**
* Provides access to Azure Queue via their REST API.
@ -63,13 +51,11 @@ import org.jclouds.rest.annotations.XMLResponseParser;
* All commands return a Future of the result from Azure Queue. Any exceptions incurred during
* processing will be wrapped in an {@link ExecutionException} as documented in {@link Future#get()}.
*
* @see AzureQueueAsyncClient
* @see <a href="http://msdn.microsoft.com/en-us/library/dd135733.aspx" />
* @author Adrian Cole
*/
@SkipEncoding('/')
@RequestFilters(SharedKeyAuthentication.class)
@Headers(keys = AzureStorageHeaders.VERSION, values = "2009-07-17")
@Endpoint(AzureQueue.class)
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface AzureQueueClient {
/**
@ -81,10 +67,6 @@ public interface AzureQueueClient {
* controls the number or type of results requested
* @see ListOptions
*/
@GET
@XMLResponseParser(AccountNameEnumerationResultsHandler.class)
@Path("/")
@QueryParams(keys = "comp", values = "list")
BoundedSortedSet<QueueMetadata> listQueues(ListOptions... listOptions);
/**
@ -104,9 +86,6 @@ public interface AzureQueueClient {
* @see CreateQueueOptions
*
*/
@PUT
@Path("{queue}")
@QueryParams(keys = "restype", values = "queue")
boolean createQueue(@PathParam("queue") String queue, CreateOptions... options);
/**
@ -118,9 +97,6 @@ public interface AzureQueueClient {
* collection.
*
*/
@DELETE
@Path("{queue}")
@QueryParams(keys = "restype", values = "queue")
boolean deleteQueue(@PathParam("queue") String queue);
}

View File

@ -50,12 +50,13 @@ import com.google.inject.TypeLiteral;
* @author Adrian Cole
* @see AzureQueueContext
*/
public class AzureQueueContextBuilder extends RestContextBuilder<AzureQueueClient> {
private static final TypeLiteral<AzureQueueClient> connectionType = new TypeLiteral<AzureQueueClient>() {
};
public class AzureQueueContextBuilder extends
RestContextBuilder<AzureQueueAsyncClient, AzureQueueClient> {
public AzureQueueContextBuilder(Properties properties) {
super(connectionType, properties);
super(new TypeLiteral<AzureQueueAsyncClient>() {
}, new TypeLiteral<AzureQueueClient>() {
}, properties);
}
@Override

View File

@ -42,23 +42,23 @@ import com.google.inject.Module;
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see AzureQueueClient
* @see AzureQueueAsyncClient
*/
public class AzureQueueContextFactory {
public static RestContext<AzureQueueClient> createContext(Properties properties,
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(Properties properties,
Module... modules) {
return new AzureQueueContextBuilder(new AzureQueuePropertiesBuilder(properties).build())
.withModules(modules).buildContext();
}
public static RestContext<AzureQueueClient> createContext(String account, String encodedKey,
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(String account, String encodedKey,
Module... modules) {
return new AzureQueueContextBuilder(new AzureQueuePropertiesBuilder(account, encodedKey)
.build()).withModules(modules).buildContext();
}
public static RestContext<AzureQueueClient> createContext(URI endpoint, String account,
public static RestContext<AzureQueueAsyncClient, AzureQueueClient> createContext(URI endpoint, String account,
String encodedKey, Module... modules) {
return new AzureQueueContextBuilder(new AzureQueuePropertiesBuilder(account, encodedKey)
.withEndpoint(endpoint).build()).withModules(modules).buildContext();

View File

@ -29,6 +29,7 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.azure.storage.AzureQueue;
import org.jclouds.azure.storage.queue.AzureQueueAsyncClient;
import org.jclouds.azure.storage.queue.AzureQueueClient;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.http.RequiresHttp;
@ -48,10 +49,11 @@ public class AzureQueueContextModule extends AbstractModule {
@Provides
@Singleton
RestContext<AzureQueueClient> provideContext(Closer closer, AzureQueueClient defaultApi,
@AzureQueue URI endPoint,
RestContext<AzureQueueAsyncClient, AzureQueueClient> provideContext(Closer closer,
AzureQueueAsyncClient asynchApi, AzureQueueClient defaultApi, @AzureQueue URI endPoint,
@Named(AzureStorageConstants.PROPERTY_AZURESTORAGE_ACCOUNT) String account) {
return new RestContextImpl<AzureQueueClient>(closer, defaultApi, endPoint, account);
return new RestContextImpl<AzureQueueAsyncClient, AzureQueueClient>(closer, asynchApi,
defaultApi, endPoint, account);
}
}

View File

@ -30,8 +30,10 @@ import javax.inject.Singleton;
import org.jclouds.azure.storage.AzureQueue;
import org.jclouds.azure.storage.config.AzureStorageRestClientModule;
import org.jclouds.azure.storage.queue.AzureQueueAsyncClient;
import org.jclouds.azure.storage.queue.AzureQueueClient;
import org.jclouds.azure.storage.queue.reference.AzureQueueConstants;
import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestClientFactory;
@ -57,8 +59,15 @@ public class AzureQueueRestClientModule extends AzureStorageRestClientModule {
@Provides
@Singleton
protected AzureQueueClient provideAzureStorageClient(RestClientFactory factory) {
return factory.create(AzureQueueClient.class);
protected AzureQueueAsyncClient provideAsyncClient(RestClientFactory factory) {
return factory.create(AzureQueueAsyncClient.class);
}
@Provides
@Singleton
public AzureQueueClient provideClient(AzureQueueAsyncClient client)
throws IllegalArgumentException, SecurityException, NoSuchMethodException {
return SyncProxy.create(AzureQueueClient.class, client);
}
}

View File

@ -33,8 +33,6 @@ import java.net.URI;
import java.net.URL;
import java.security.SecureRandom;
import java.util.SortedSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.jclouds.azure.storage.AzureStorageResponseException;
@ -78,8 +76,7 @@ public class AzureBlobClientLiveTest {
@Test
public void testListContainers() throws Exception {
SortedSet<ListableContainerProperties> response = connection.listContainers().get(10,
TimeUnit.SECONDS);
SortedSet<ListableContainerProperties> response = connection.listContainers();
assert null != response;
long initialContainerCount = response.size();
assertTrue(initialContainerCount >= 0);
@ -96,11 +93,8 @@ public class AzureBlobClientLiveTest {
while (!created) {
privateContainer = containerPrefix + new SecureRandom().nextInt();
try {
created = connection.createContainer(
privateContainer,
CreateContainerOptions.Builder
.withMetadata(ImmutableMultimap.of("foo", "bar"))).get(10,
TimeUnit.SECONDS);
created = connection.createContainer(privateContainer, CreateContainerOptions.Builder
.withMetadata(ImmutableMultimap.of("foo", "bar")));
} catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
if (htpe.getResponse().getStatusCode() == 409)
@ -108,12 +102,11 @@ public class AzureBlobClientLiveTest {
throw e;
}
}
SortedSet<ListableContainerProperties> response = connection.listContainers().get(10,
TimeUnit.SECONDS);
SortedSet<ListableContainerProperties> response = connection.listContainers();
assert null != response;
long containerCount = response.size();
assertTrue(containerCount >= 1);
ListBlobsResponse list = connection.listBlobs(privateContainer).get(10, TimeUnit.SECONDS);
ListBlobsResponse list = connection.listBlobs(privateContainer);
assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/%s",
account, privateContainer)));
// TODO ... check to see the container actually exists
@ -125,8 +118,8 @@ public class AzureBlobClientLiveTest {
while (!created) {
publicContainer = containerPrefix + new SecureRandom().nextInt();
try {
created = connection.createContainer(publicContainer,
CreateContainerOptions.Builder.withPublicAcl()).get(10, TimeUnit.SECONDS);
created = connection.createContainer(publicContainer, CreateContainerOptions.Builder
.withPublicAcl());
} catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
if (htpe.getResponse().getStatusCode() == 409)
@ -143,43 +136,41 @@ public class AzureBlobClientLiveTest {
@Test(timeOut = 5 * 60 * 1000)
public void testCreatePublicRootContainer() throws Exception {
try {
connection.deleteRootContainer().get(10, TimeUnit.SECONDS);
} catch (ExecutionException e) {
connection.deleteRootContainer();
} catch (AzureStorageResponseException e) {
sleepIfWaitingForDeleteToFinish(e);
}
boolean created = false;
while (!created) {
try {
created = connection.createRootContainer().get(10, TimeUnit.SECONDS);
} catch (ExecutionException e) {
AzureStorageResponseException htpe = (AzureStorageResponseException) e.getCause()
.getCause();
created = connection.createRootContainer();
} catch (AzureStorageResponseException htpe) {
if (htpe.getResponse().getStatusCode() == 409) {// TODO look for specific message
Thread.sleep(5000);
continue;
} else {
throw htpe;
}
throw e;
}
}
ListBlobsResponse list = connection.listBlobs().get(10, TimeUnit.SECONDS);
ListBlobsResponse list = connection.listBlobs();
assertEquals(list.getUrl(), URI.create(String.format(
"https://%s.blob.core.windows.net/%%24root", account)));
}
private void sleepIfWaitingForDeleteToFinish(ExecutionException e) throws InterruptedException {
if (e.getCause() instanceof AzureStorageResponseException) {
if (((AzureStorageResponseException) e.getCause()).getResponse().getStatusCode() == 409) {
Thread.sleep(5000);
}
private void sleepIfWaitingForDeleteToFinish(AzureStorageResponseException e)
throws InterruptedException {
if (e.getResponse().getStatusCode() == 409) {
Thread.sleep(5000);
}
}
@Test
public void testListContainersWithOptions() throws Exception {
BoundedSortedSet<ListableContainerProperties> response = connection.listContainers(
ListOptions.Builder.prefix(privateContainer).maxResults(1))
.get(10, TimeUnit.SECONDS);
BoundedSortedSet<ListableContainerProperties> response = connection
.listContainers(ListOptions.Builder.prefix(privateContainer).maxResults(1));
assert null != response;
long initialContainerCount = response.size();
assertTrue(initialContainerCount >= 0);
@ -189,7 +180,7 @@ public class AzureBlobClientLiveTest {
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testCreatePublicRootContainer" })
public void testDeleteRootContainer() throws Exception {
assert connection.deleteRootContainer().get(10, TimeUnit.SECONDS);
assert connection.deleteRootContainer();
// TODO loop for up to 30 seconds checking if they are really gone
}
@ -198,22 +189,18 @@ public class AzureBlobClientLiveTest {
public void testListOwnedContainers() throws Exception {
// Test default listing
SortedSet<ListableContainerProperties> response = connection.listContainers().get(10,
TimeUnit.SECONDS);
SortedSet<ListableContainerProperties> response = connection.listContainers();
// assertEquals(response.size(), initialContainerCount + 2);// if the containers already
// exist, this will fail
// Test listing with options
response = connection
.listContainers(
ListOptions.Builder.prefix(
privateContainer.substring(0, privateContainer.length() - 1))
.maxResults(1)).get(10, TimeUnit.SECONDS);
response = connection.listContainers(ListOptions.Builder.prefix(
privateContainer.substring(0, privateContainer.length() - 1)).maxResults(1));
assertEquals(response.size(), 1);
assertEquals(response.first().getName(), privateContainer);
response = connection.listContainers(
ListOptions.Builder.prefix(publicContainer).maxResults(1)).get(10, TimeUnit.SECONDS);
response = connection.listContainers(ListOptions.Builder.prefix(publicContainer)
.maxResults(1));
assertEquals(response.size(), 1);
assertEquals(response.first().getName(), publicContainer);
@ -221,14 +208,14 @@ public class AzureBlobClientLiveTest {
@Test
public void testDeleteOneContainer() throws Exception {
connection.deleteContainer("does-not-exist").get(10, TimeUnit.SECONDS);
connection.deleteContainer("does-not-exist");
}
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testListOwnedContainers",
"testObjectOperations" })
public void testDeleteContainer() throws Exception {
connection.deleteContainer(privateContainer).get(10, TimeUnit.SECONDS);
connection.deleteContainer(publicContainer).get(10, TimeUnit.SECONDS);
connection.deleteContainer(privateContainer);
connection.deleteContainer(publicContainer);
// TODO loop for up to 30 seconds checking if they are really gone
}
@ -246,7 +233,7 @@ public class AzureBlobClientLiveTest {
object.getProperties().setContentType("text/plain");
object.getProperties().getMetadata().put("Metadata", "metadata-value");
byte[] md5 = object.getProperties().getContentMD5();
String newEtag = connection.putBlob(privateContainer, object).get(10, TimeUnit.SECONDS);
String newEtag = connection.putBlob(privateContainer, object);
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(object.getProperties()
.getContentMD5()));
@ -285,14 +272,13 @@ public class AzureBlobClientLiveTest {
// Test GET of missing object
try {
connection.getBlob(privateContainer, "non-existent-object").get(10, TimeUnit.SECONDS);
connection.getBlob(privateContainer, "non-existent-object");
assert false;
} catch (Exception e) {
e.printStackTrace();
}
// Test GET of object (including updated metadata)
AzureBlob getBlob = connection.getBlob(privateContainer, object.getProperties().getName())
.get(120, TimeUnit.SECONDS);
AzureBlob getBlob = connection.getBlob(privateContainer, object.getProperties().getName());
assertEquals(IOUtils.toString((InputStream) getBlob.getData()), data);
// TODO assertEquals(getBlob.getName(), object.getProperties().getName());
assertEquals(getBlob.getContentLength(), new Long(data.length()));
@ -316,7 +302,7 @@ public class AzureBlobClientLiveTest {
String incorrectEtag = "0" + correctEtag.substring(1);
object.getProperties().setETag(incorrectEtag);
try {
connection.putBlob(privateContainer, object).get(10, TimeUnit.SECONDS);
connection.putBlob(privateContainer, object);
} catch (Throwable e) {
assertEquals(e.getCause().getClass(), HttpResponseException.class);
assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 422);
@ -327,15 +313,15 @@ public class AzureBlobClientLiveTest {
object.getProperties().setName("chunked-object");
object.setData(bais);
object.setContentLength(new Long(data.getBytes().length));
newEtag = connection.putBlob(privateContainer, object).get(10, TimeUnit.SECONDS);
newEtag = connection.putBlob(privateContainer, object);
assertEquals(HttpUtils.toHexString(md5), HttpUtils.toHexString(getBlob.getProperties()
.getContentMD5()));
// Test GET with options
// Non-matching ETag
try {
connection.getBlob(privateContainer, object.getProperties().getName(),
GetOptions.Builder.ifETagDoesntMatch(newEtag)).get(120, TimeUnit.SECONDS);
connection.getBlob(privateContainer, object.getProperties().getName(), GetOptions.Builder
.ifETagDoesntMatch(newEtag));
} catch (Exception e) {
assertEquals(e.getCause().getClass(), HttpResponseException.class);
assertEquals(((HttpResponseException) e.getCause()).getResponse().getStatusCode(), 304);
@ -343,7 +329,7 @@ public class AzureBlobClientLiveTest {
// Matching ETag
getBlob = connection.getBlob(privateContainer, object.getProperties().getName(),
GetOptions.Builder.ifETagMatches(newEtag)).get(120, TimeUnit.SECONDS);
GetOptions.Builder.ifETagMatches(newEtag));
assertEquals(getBlob.getProperties().getETag(), newEtag);
// Range
@ -355,7 +341,7 @@ public class AzureBlobClientLiveTest {
// TimeUnit.SECONDS);
// assertEquals(IOUtils.toString((InputStream) getBlob.getData()), data.substring(8));
connection.deleteBlob(privateContainer, "object").get(10, TimeUnit.SECONDS);
connection.deleteBlob(privateContainer, "chunked-object").get(10, TimeUnit.SECONDS);
connection.deleteBlob(privateContainer, "object");
connection.deleteBlob(privateContainer, "chunked-object");
}
}

View File

@ -81,10 +81,10 @@ import com.google.inject.TypeLiteral;
public class AzureBlobClientTest {
public void testListContainers() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("listContainers", Array.newInstance(
Method method = AzureBlobAsyncClient.class.getMethod("listContainers", Array.newInstance(
ListOptions.class, 0).getClass());
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] {});
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/");
@ -99,10 +99,10 @@ public class AzureBlobClientTest {
}
public void testListContainersOptions() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("listContainers", Array.newInstance(
Method method = AzureBlobAsyncClient.class.getMethod("listContainers", Array.newInstance(
ListOptions.class, 0).getClass());
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] { maxResults(1).marker("marker").prefix("prefix") });
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/");
@ -120,10 +120,10 @@ public class AzureBlobClientTest {
}
public void testCreateContainer() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("createContainer", String.class, Array
Method method = AzureBlobAsyncClient.class.getMethod("createContainer", String.class, Array
.newInstance(CreateContainerOptions.class, 0).getClass());
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] { "container" });
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
@ -141,9 +141,9 @@ public class AzureBlobClientTest {
}
public void testDeleteContainer() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("deleteContainer", String.class);
Method method = AzureBlobAsyncClient.class.getMethod("deleteContainer", String.class);
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] { "container" });
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
@ -160,10 +160,10 @@ public class AzureBlobClientTest {
}
public void testCreateContainerOptions() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("createContainer", String.class, Array
Method method = AzureBlobAsyncClient.class.getMethod("createContainer", String.class, Array
.newInstance(CreateContainerOptions.class, 0).getClass());
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] { "container",
withPublicAcl().withMetadata(ImmutableMultimap.of("foo", "bar")) });
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
@ -185,10 +185,10 @@ public class AzureBlobClientTest {
}
public void testCreateRootContainer() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("createRootContainer", Array.newInstance(
CreateContainerOptions.class, 0).getClass());
Method method = AzureBlobAsyncClient.class.getMethod("createRootContainer", Array
.newInstance(CreateContainerOptions.class, 0).getClass());
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] {});
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/$root");
@ -206,9 +206,9 @@ public class AzureBlobClientTest {
}
public void testDeleteRootContainer() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("deleteRootContainer");
Method method = AzureBlobAsyncClient.class.getMethod("deleteRootContainer");
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] {});
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/$root");
@ -225,10 +225,10 @@ public class AzureBlobClientTest {
}
public void testCreateRootContainerOptions() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("createRootContainer", Array.newInstance(
CreateContainerOptions.class, 0).getClass());
Method method = AzureBlobAsyncClient.class.getMethod("createRootContainer", Array
.newInstance(CreateContainerOptions.class, 0).getClass());
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] { withPublicAcl().withMetadata(ImmutableMultimap.of("foo", "bar")) });
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/$root");
@ -249,10 +249,10 @@ public class AzureBlobClientTest {
}
public void testListBlobs() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("listBlobs", String.class, Array.newInstance(
ListBlobsOptions.class, 0).getClass());
Method method = AzureBlobAsyncClient.class.getMethod("listBlobs", String.class, Array
.newInstance(ListBlobsOptions.class, 0).getClass());
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] { "container" });
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
@ -267,10 +267,10 @@ public class AzureBlobClientTest {
}
public void testListRootBlobs() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("listBlobs", Array.newInstance(
Method method = AzureBlobAsyncClient.class.getMethod("listBlobs", Array.newInstance(
ListBlobsOptions.class, 0).getClass());
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] {});
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/$root");
@ -285,9 +285,9 @@ public class AzureBlobClientTest {
}
public void testContainerProperties() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("getContainerProperties", String.class);
Method method = AzureBlobAsyncClient.class.getMethod("getContainerProperties", String.class);
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] { "container" });
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
@ -302,10 +302,10 @@ public class AzureBlobClientTest {
}
public void testSetResourceMetadata() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("setResourceMetadata", String.class,
Method method = AzureBlobAsyncClient.class.getMethod("setResourceMetadata", String.class,
Map.class);
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] { "container", ImmutableMap.of("key", "value") });
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/container");
@ -324,9 +324,9 @@ public class AzureBlobClientTest {
}
public void testSetBlobMetadata() throws SecurityException, NoSuchMethodException {
Method method = AzureBlobClient.class.getMethod("setBlobMetadata", String.class,
Method method = AzureBlobAsyncClient.class.getMethod("setBlobMetadata", String.class,
String.class, Map.class);
GeneratedHttpRequest<AzureBlobClient> httpMethod = processor.createRequest(method,
GeneratedHttpRequest<AzureBlobAsyncClient> httpMethod = processor.createRequest(method,
new Object[] { "container", "blob", ImmutableMap.of("key", "value") });
assertEquals(httpMethod.getEndpoint().getHost(), "myaccount.blob.core.windows.net");
assertEquals(httpMethod.getEndpoint().getPath(), "/container/blob");
@ -375,9 +375,9 @@ public class AzureBlobClientTest {
}, new AzureStorageRestClientModule(), new RestModule(), new ExecutorServiceModule(
new WithinThreadExecutorService()), new JavaUrlHttpCommandExecutorServiceModule());
processor = injector.getInstance(Key
.get(new TypeLiteral<RestAnnotationProcessor<AzureBlobClient>>() {
.get(new TypeLiteral<RestAnnotationProcessor<AzureBlobAsyncClient>>() {
}));
}
RestAnnotationProcessor<AzureBlobClient> processor;
RestAnnotationProcessor<AzureBlobAsyncClient> processor;
}

View File

@ -33,7 +33,7 @@ import org.jclouds.azure.storage.blob.config.AzureBlobContextModule;
import org.jclouds.azure.storage.blob.config.AzureBlobRestClientModule;
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
import org.jclouds.azure.storage.blob.domain.AzureBlob;
import org.jclouds.azure.storage.blob.internal.StubAzureBlobClient;
import org.jclouds.azure.storage.blob.internal.StubAzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.reference.AzureBlobConstants;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.blobstore.domain.Blob;
@ -66,11 +66,11 @@ public class AzureBlobContextBuilderTest {
}
public void testBuildContext() {
RestContext<AzureBlobClient> context = new AzureBlobContextBuilder(
RestContext<AzureBlobAsyncClient, AzureBlobClient> context = new AzureBlobContextBuilder(
new AzureBlobPropertiesBuilder("id", "secret").build()).withModules(
new AzureBlobStubClientModule()).buildContext();
assertEquals(context.getClass(), RestContextImpl.class);
assertEquals(context.getApi().getClass(), StubAzureBlobClient.class);
assertEquals(context.getAsyncApi().getClass(), StubAzureBlobAsyncClient.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("https://localhost/azurestub"));
}
@ -78,7 +78,7 @@ public class AzureBlobContextBuilderTest {
public void testBuildInjector() {
Injector i = new AzureBlobContextBuilder(new AzureBlobPropertiesBuilder("id", "secret")
.build()).withModules(new AzureBlobStubClientModule()).buildInjector();
assert i.getInstance(Key.get(new TypeLiteral<RestContext<AzureBlobClient>>() {
assert i.getInstance(Key.get(new TypeLiteral<RestContext<AzureBlobAsyncClient, AzureBlobClient>>() {
})) != null;
assert i.getInstance(AzureBlob.class) != null;
assert i.getInstance(Blob.class) != null;

View File

@ -30,6 +30,7 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.AzureBlobPropertiesBuilder;
import org.jclouds.azure.storage.blob.blobstore.config.AzureBlobStoreContextModule;
@ -37,7 +38,7 @@ import org.jclouds.azure.storage.blob.config.AzureBlobRestClientModule;
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
import org.jclouds.azure.storage.blob.domain.AzureBlob;
import org.jclouds.azure.storage.blob.domain.internal.AzureBlobImpl;
import org.jclouds.azure.storage.blob.internal.StubAzureBlobClient;
import org.jclouds.azure.storage.blob.internal.StubAzureBlobAsyncClient;
import org.jclouds.azure.storage.reference.AzureStorageConstants;
import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob;
@ -74,19 +75,19 @@ public class AzureBlobStoreContextBuilderTest {
}
public void testBuildContext() {
BlobStoreContext<AzureBlobClient> context = newBuilder().buildContext();
BlobStoreContext<AzureBlobAsyncClient, AzureBlobClient> context = newBuilder().buildContext();
assertEquals(context.getClass(), BlobStoreContextImpl.class);
assertEquals(context.getApi().getClass(), StubAzureBlobClient.class);
assertEquals(context.getBlobStore().getClass(), AzureBlobStore.class);
assertEquals(context.getApi().newBlob().getClass(), AzureBlobImpl.class);
assertEquals(context.getBlobStore().newBlob().getClass(), BlobImpl.class);
assertEquals(context.getAsyncApi().getClass(), StubAzureBlobAsyncClient.class);
assertEquals(context.getAsyncBlobStore().getClass(), AzureAsyncBlobStore.class);
assertEquals(context.getAsyncApi().newBlob().getClass(), AzureBlobImpl.class);
assertEquals(context.getAsyncBlobStore().newBlob().getClass(), BlobImpl.class);
assertEquals(context.getAccount(), "id");
assertEquals(context.getEndPoint(), URI.create("https://localhost/azurestub"));
}
public void testBuildInjector() {
Injector i = newBuilder().buildInjector();
assert i.getInstance(Key.get(new TypeLiteral<BlobStoreContext<AzureBlobClient>>() {
assert i.getInstance(Key.get(new TypeLiteral<BlobStoreContext<AzureBlobAsyncClient, AzureBlobClient>>() {
})) != null;
assert i.getInstance(AzureBlob.class) != null;
assert i.getInstance(Blob.class) != null;

View File

@ -25,6 +25,7 @@ package org.jclouds.azure.storage.blob.blobstore.config;
import static org.testng.Assert.assertEquals;
import org.jclouds.azure.storage.blob.AzureBlobAsyncClient;
import org.jclouds.azure.storage.blob.AzureBlobClient;
import org.jclouds.azure.storage.blob.blobstore.strategy.FindMD5InBlobProperties;
import org.jclouds.azure.storage.blob.config.AzureBlobStubClientModule;
@ -74,8 +75,8 @@ public class AzureBlobStoreModuleTest {
void testContextImpl() {
Injector injector = createInjector();
BlobStoreContext<AzureBlobClient> handler = injector.getInstance(Key
.get(new TypeLiteral<BlobStoreContext<AzureBlobClient>>() {
BlobStoreContext<AzureBlobAsyncClient, AzureBlobClient> handler = injector.getInstance(Key
.get(new TypeLiteral<BlobStoreContext<AzureBlobAsyncClient, AzureBlobClient>>() {
}));
assertEquals(handler.getClass(), BlobStoreContextImpl.class);
ContainsValueInListStrategy valueList = injector

Some files were not shown because too many files have changed in this diff Show More