mirror of
https://github.com/apache/jclouds.git
synced 2025-02-16 06:56:45 +00:00
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:
parent
2285f36bd3
commit
bc238bc507
@ -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);
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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>>() {
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
||||
}
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
||||
}
|
@ -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)
|
||||
|
@ -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> {
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
295
aws/core/src/main/java/org/jclouds/aws/ec2/EC2AsyncClient.java
Normal file
295
aws/core/src/main/java/org/jclouds/aws/ec2/EC2AsyncClient.java
Normal 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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
239
aws/core/src/main/java/org/jclouds/aws/s3/S3AsyncClient.java
Normal file
239
aws/core/src/main/java/org/jclouds/aws/s3/S3AsyncClient.java
Normal 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);
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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();
|
||||
|
@ -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>>() {
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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>>() {
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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> {
|
||||
|
||||
}
|
@ -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> {
|
||||
|
||||
}
|
@ -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> {
|
||||
|
||||
}
|
@ -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> {
|
||||
|
||||
}
|
@ -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> {
|
||||
|
||||
}
|
@ -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> {
|
||||
|
||||
}
|
@ -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> {
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user