From e55f42416788cee125a91017f694c44c55124f79 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Fri, 3 Oct 2014 21:38:57 -0700 Subject: [PATCH] JCLOUDS-40 unasync atmos. --- apis/atmos/pom.xml | 1 - .../org/jclouds/atmos/AtmosApiMetadata.java | 26 +- .../org/jclouds/atmos/AtmosAsyncClient.java | 230 -------------- .../java/org/jclouds/atmos/AtmosClient.java | 147 +++++++-- .../atmos/blobstore/AtmosAsyncBlobStore.java | 289 ------------------ .../blobstore/AtmosBlobRequestSigner.java | 8 +- .../config/AtmosBlobStoreContextModule.java | 7 +- ...entModule.java => AtmosHttpApiModule.java} | 9 +- .../jclouds/atmos/AtmosClientLiveTest.java | 2 +- ...ncClientTest.java => AtmosClientTest.java} | 49 ++- .../blobstore/AtmosBlobRequestSignerTest.java | 14 +- .../atmos/filters/SignRequestTest.java | 10 +- .../atmos/internal/StubAtmosAsyncClient.java | 246 --------------- 13 files changed, 179 insertions(+), 859 deletions(-) delete mode 100644 apis/atmos/src/main/java/org/jclouds/atmos/AtmosAsyncClient.java delete mode 100644 apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosAsyncBlobStore.java rename apis/atmos/src/main/java/org/jclouds/atmos/config/{AtmosRestClientModule.java => AtmosHttpApiModule.java} (92%) rename apis/atmos/src/test/java/org/jclouds/atmos/{AtmosAsyncClientTest.java => AtmosClientTest.java} (87%) delete mode 100644 apis/atmos/src/test/java/org/jclouds/atmos/internal/StubAtmosAsyncClient.java diff --git a/apis/atmos/pom.xml b/apis/atmos/pom.xml index 2d275fe6a0..aa53dca2c6 100644 --- a/apis/atmos/pom.xml +++ b/apis/atmos/pom.xml @@ -91,7 +91,6 @@ - ${test.initializer} ${jclouds.blobstore.httpstream.url} ${jclouds.blobstore.httpstream.md5} ${test.atmos.endpoint} diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/AtmosApiMetadata.java b/apis/atmos/src/main/java/org/jclouds/atmos/AtmosApiMetadata.java index 874f6e12a7..109ef1f2f9 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/AtmosApiMetadata.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/AtmosApiMetadata.java @@ -15,6 +15,7 @@ * limitations under the License. */ package org.jclouds.atmos; + import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import static org.jclouds.reflect.Reflection2.typeToken; @@ -23,27 +24,15 @@ import java.net.URI; import java.util.Properties; import org.jclouds.atmos.blobstore.config.AtmosBlobStoreContextModule; -import org.jclouds.atmos.config.AtmosRestClientModule; +import org.jclouds.atmos.config.AtmosHttpApiModule; import org.jclouds.blobstore.BlobStoreContext; +import org.jclouds.rest.internal.BaseHttpApiMetadata; import org.jclouds.rest.internal.BaseRestApiMetadata; import com.google.common.collect.ImmutableSet; -import com.google.common.reflect.TypeToken; import com.google.inject.Module; -/** - * Implementation of {@link ApiMetadata} for EMC Atmos API - */ -public class AtmosApiMetadata extends BaseRestApiMetadata { - - /** - * @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(AtmosClient.class)} as - * {@link AtmosAsyncClient} interface will be removed in jclouds 1.7. - */ - @Deprecated - public static final TypeToken> CONTEXT_TOKEN = new TypeToken>() { - private static final long serialVersionUID = 1L; - }; +public class AtmosApiMetadata extends BaseHttpApiMetadata { private static Builder builder() { return new Builder(); @@ -69,10 +58,9 @@ public class AtmosApiMetadata extends BaseRestApiMetadata { return properties; } - public static class Builder extends BaseRestApiMetadata.Builder { - @SuppressWarnings("deprecation") + public static class Builder extends BaseHttpApiMetadata.Builder { protected Builder() { - super(AtmosClient.class, AtmosAsyncClient.class); + super(AtmosClient.class); id("atmos") .name("EMC's Atmos API") .identityName("Subtenant ID (UID)") @@ -82,7 +70,7 @@ public class AtmosApiMetadata extends BaseRestApiMetadata { .defaultEndpoint("https://accesspoint.atmosonline.com") .defaultProperties(AtmosApiMetadata.defaultProperties()) .view(typeToken(BlobStoreContext.class)) - .defaultModules(ImmutableSet.>of(AtmosRestClientModule.class, AtmosBlobStoreContextModule.class)); + .defaultModules(ImmutableSet.>of(AtmosHttpApiModule.class, AtmosBlobStoreContextModule.class)); } @Override diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/AtmosAsyncClient.java b/apis/atmos/src/main/java/org/jclouds/atmos/AtmosAsyncClient.java deleted file mode 100644 index 5334487f7f..0000000000 --- a/apis/atmos/src/main/java/org/jclouds/atmos/AtmosAsyncClient.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * 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.atmos; - -import static com.google.common.net.HttpHeaders.EXPECT; - -import java.io.Closeable; -import java.net.URI; - -import javax.inject.Named; -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.Produces; -import javax.ws.rs.core.MediaType; - -import org.jclouds.Fallbacks.FalseOnNotFoundOr404; -import org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.atmos.binders.BindMetadataToHeaders; -import org.jclouds.atmos.domain.AtmosObject; -import org.jclouds.atmos.domain.BoundedSet; -import org.jclouds.atmos.domain.DirectoryEntry; -import org.jclouds.atmos.domain.SystemMetadata; -import org.jclouds.atmos.domain.UserMetadata; -import org.jclouds.atmos.fallbacks.TrueOn404FalseOnPathNotEmpty; -import org.jclouds.atmos.filters.SignRequest; -import org.jclouds.atmos.functions.AtmosObjectName; -import org.jclouds.atmos.functions.ParseDirectoryListFromContentAndHeaders; -import org.jclouds.atmos.functions.ParseNullableURIFromListOrLocationHeaderIf20x; -import org.jclouds.atmos.functions.ParseObjectFromHeadersAndHttpContent; -import org.jclouds.atmos.functions.ParseSystemMetadataFromHeaders; -import org.jclouds.atmos.functions.ParseUserMetadataFromHeaders; -import org.jclouds.atmos.functions.ReturnTrueIfGroupACLIsOtherRead; -import org.jclouds.atmos.options.ListOptions; -import org.jclouds.atmos.options.PutOptions; -import org.jclouds.blobstore.BlobStoreFallbacks.NullOnKeyAlreadyExists; -import org.jclouds.blobstore.BlobStoreFallbacks.ThrowContainerNotFoundOn404; -import org.jclouds.blobstore.BlobStoreFallbacks.ThrowKeyNotFoundOn404; -import org.jclouds.http.options.GetOptions; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.rest.annotations.BinderParam; -import org.jclouds.rest.annotations.Fallback; -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 com.google.common.util.concurrent.ListenableFuture; -import com.google.inject.Provides; - -/** - * Provides asynchronous access to EMC Atmos Online Storage resources via their REST API. - *

- * - * @see AtmosClient - * @see - * - * @deprecated please use {@code org.jclouds.ContextBuilder#buildApi(AtmosClient.class)} as - * {@link AtmosAsyncClient} interface will be removed in jclouds 1.7. - */ -@Deprecated -@RequestFilters(SignRequest.class) -@Path("/rest/namespace") -public interface AtmosAsyncClient extends Closeable { - /** - * Creates a default implementation of AtmosObject - */ - @Provides - AtmosObject newObject(); - - /** - * @see AtmosClient#listDirectories - */ - @Named("ListDirectory") - @GET - @Path("/") - @ResponseParser(ParseDirectoryListFromContentAndHeaders.class) - @Consumes(MediaType.TEXT_XML) - ListenableFuture> listDirectories(ListOptions... options); - - /** - * @see AtmosClient#listDirectory - */ - @Named("ListDirectory") - @GET - @Path("/{directoryName}/") - @ResponseParser(ParseDirectoryListFromContentAndHeaders.class) - @Fallback(ThrowContainerNotFoundOn404.class) - @Consumes(MediaType.TEXT_XML) - ListenableFuture> listDirectory( - @PathParam("directoryName") String directoryName, ListOptions... options); - - /** - * @see AtmosClient#createDirectory - */ - @Named("CreateDirectory") - @POST - @Path("/{directoryName}/") - @Fallback(NullOnKeyAlreadyExists.class) - @Produces(MediaType.APPLICATION_OCTET_STREAM) - @Consumes(MediaType.WILDCARD) - ListenableFuture createDirectory(@PathParam("directoryName") String directoryName, PutOptions... options); - - /** - * @see AtmosClient#createFile - */ - @Nullable - @Named("CreateObject") - @POST - @Path("/{parent}/{name}") - @Headers(keys = EXPECT, values = "100-continue") - @ResponseParser(ParseNullableURIFromListOrLocationHeaderIf20x.class) - @Consumes(MediaType.WILDCARD) - ListenableFuture createFile( - @PathParam("parent") String parent, - @PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindMetadataToHeaders.class) AtmosObject object, - PutOptions... options); - - /** - * @see AtmosClient#updateFile - */ - @Named("UpdateObject") - @PUT - @Path("/{parent}/{name}") - @Headers(keys = EXPECT, values = "100-continue") - @Fallback(ThrowKeyNotFoundOn404.class) - @Consumes(MediaType.WILDCARD) - ListenableFuture updateFile( - @PathParam("parent") String parent, - @PathParam("name") @ParamParser(AtmosObjectName.class) @BinderParam(BindMetadataToHeaders.class) AtmosObject object, - PutOptions... options); - - /** - * @see AtmosClient#readFile - */ - @Named("ReadObject") - @GET - @ResponseParser(ParseObjectFromHeadersAndHttpContent.class) - @Fallback(NullOnNotFoundOr404.class) - @Path("/{path}") - @Consumes(MediaType.WILDCARD) - ListenableFuture readFile(@PathParam("path") String path, GetOptions... options); - - /** - * @see AtmosClient#headFile - */ - @Named("GetObjectMetadata") - @HEAD - @ResponseParser(ParseObjectFromHeadersAndHttpContent.class) - @Fallback(NullOnNotFoundOr404.class) - @Path("/{path}") - @Consumes(MediaType.WILDCARD) - ListenableFuture headFile(@PathParam("path") String path); - - /** - * @see AtmosClient#getSystemMetadata - */ - @Named("GetSystemMetadata") - @HEAD - @ResponseParser(ParseSystemMetadataFromHeaders.class) - @Fallback(NullOnNotFoundOr404.class) - // currently throws 403 errors @QueryParams(keys = "metadata/system") - @Path("/{path}") - @Consumes(MediaType.WILDCARD) - ListenableFuture getSystemMetadata(@PathParam("path") String path); - - /** - * @see AtmosClient#getUserMetadata - */ - @Named("GetUserMetadata") - @HEAD - @ResponseParser(ParseUserMetadataFromHeaders.class) - @Fallback(NullOnNotFoundOr404.class) - @Path("/{path}") - @QueryParams(keys = "metadata/user") - @Consumes(MediaType.WILDCARD) - ListenableFuture getUserMetadata(@PathParam("path") String path); - - /** - * @see AtmosClient#deletePath - */ - @Named("DeleteObject") - @DELETE - @Fallback(TrueOn404FalseOnPathNotEmpty.class) - @Path("/{path}") - @Consumes(MediaType.WILDCARD) - ListenableFuture deletePath(@PathParam("path") String path); - - /** - * @see AtmosClient#pathExists - */ - @Named("GetObjectMetadata") - @HEAD - @Fallback(FalseOnNotFoundOr404.class) - @Path("/{path}") - @Consumes(MediaType.WILDCARD) - ListenableFuture pathExists(@PathParam("path") String path); - - /** - * @see AtmosClient#isPublic - */ - @Named("GetObjectMetadata") - @HEAD - @ResponseParser(ReturnTrueIfGroupACLIsOtherRead.class) - @Path("/{path}") - @Consumes(MediaType.WILDCARD) - @Fallback(FalseOnNotFoundOr404.class) - ListenableFuture isPublic(@PathParam("path") String path); - -} diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/AtmosClient.java b/apis/atmos/src/main/java/org/jclouds/atmos/AtmosClient.java index 38168e2141..9d5a5ce82a 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/AtmosClient.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/AtmosClient.java @@ -16,57 +16,162 @@ */ package org.jclouds.atmos; +import static com.google.common.net.HttpHeaders.EXPECT; +import static org.jclouds.Fallbacks.FalseOnNotFoundOr404; +import static org.jclouds.Fallbacks.NullOnNotFoundOr404; +import static org.jclouds.blobstore.BlobStoreFallbacks.NullOnKeyAlreadyExists; +import static org.jclouds.blobstore.BlobStoreFallbacks.ThrowContainerNotFoundOn404; +import static org.jclouds.blobstore.BlobStoreFallbacks.ThrowKeyNotFoundOn404; + import java.io.Closeable; import java.net.URI; + +import javax.inject.Named; +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.Produces; +import javax.ws.rs.core.MediaType; + +import org.jclouds.atmos.binders.BindMetadataToHeaders; import org.jclouds.atmos.domain.AtmosObject; import org.jclouds.atmos.domain.BoundedSet; import org.jclouds.atmos.domain.DirectoryEntry; import org.jclouds.atmos.domain.SystemMetadata; import org.jclouds.atmos.domain.UserMetadata; +import org.jclouds.atmos.fallbacks.TrueOn404FalseOnPathNotEmpty; +import org.jclouds.atmos.filters.SignRequest; +import org.jclouds.atmos.functions.AtmosObjectName; +import org.jclouds.atmos.functions.ParseDirectoryListFromContentAndHeaders; +import org.jclouds.atmos.functions.ParseNullableURIFromListOrLocationHeaderIf20x; +import org.jclouds.atmos.functions.ParseObjectFromHeadersAndHttpContent; +import org.jclouds.atmos.functions.ParseSystemMetadataFromHeaders; +import org.jclouds.atmos.functions.ParseUserMetadataFromHeaders; +import org.jclouds.atmos.functions.ReturnTrueIfGroupACLIsOtherRead; import org.jclouds.atmos.options.ListOptions; import org.jclouds.atmos.options.PutOptions; import org.jclouds.http.options.GetOptions; import org.jclouds.javax.annotation.Nullable; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Fallback; +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 com.google.inject.Provides; -/** - * Provides access to EMC Atmos Online Storage resources via their REST API. - *

- * - * @see AtmosAsyncClient - * @see - */ +/** Provides access to EMC Atmos Online Storage resources via their REST API. */ +@RequestFilters(SignRequest.class) +@Path("/rest/namespace") public interface AtmosClient extends Closeable { - /** - * Creates a default implementation of AtmosObject - */ + @Provides AtmosObject newObject(); + @Named("ListDirectory") + @GET + @Path("/") + @ResponseParser(ParseDirectoryListFromContentAndHeaders.class) + @Consumes(MediaType.TEXT_XML) BoundedSet listDirectories(ListOptions... options); - BoundedSet listDirectory(String directoryName, ListOptions... options); + @Named("ListDirectory") + @GET + @Path("/{directoryName}/") + @ResponseParser(ParseDirectoryListFromContentAndHeaders.class) + @Fallback(ThrowContainerNotFoundOn404.class) + @Consumes(MediaType.TEXT_XML) + BoundedSet listDirectory( + @PathParam("directoryName") String directoryName, ListOptions... options); - URI createDirectory(String directoryName, PutOptions... options); + @Named("CreateDirectory") + @POST + @Path("/{directoryName}/") + @Fallback(NullOnKeyAlreadyExists.class) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Consumes(MediaType.WILDCARD) + URI createDirectory(@PathParam("directoryName") String directoryName, PutOptions... options); @Nullable - URI createFile(String parent, AtmosObject object, PutOptions... options); + @Named("CreateObject") + @POST + @Path("/{parent}/{name}") + @Headers(keys = EXPECT, values = "100-continue") + @ResponseParser(ParseNullableURIFromListOrLocationHeaderIf20x.class) + @Consumes(MediaType.WILDCARD) + URI createFile(@PathParam("parent") String parent, @PathParam("name") @ParamParser(AtmosObjectName.class) + @BinderParam(BindMetadataToHeaders.class) AtmosObject object, PutOptions... options); - void updateFile(String parent, AtmosObject object, PutOptions... options); + @Named("UpdateObject") + @PUT + @Path("/{parent}/{name}") + @Headers(keys = EXPECT, values = "100-continue") + @Fallback(ThrowKeyNotFoundOn404.class) + @Consumes(MediaType.WILDCARD) + void updateFile(@PathParam("parent") String parent, @PathParam("name") @ParamParser(AtmosObjectName.class) + @BinderParam(BindMetadataToHeaders.class) AtmosObject object, PutOptions... options); - AtmosObject readFile(String path, GetOptions... options); + @Named("ReadObject") + @GET + @ResponseParser(ParseObjectFromHeadersAndHttpContent.class) + @Fallback(NullOnNotFoundOr404.class) + @Path("/{path}") + @Consumes(MediaType.WILDCARD) + AtmosObject readFile(@PathParam("path") String path, GetOptions... options); - AtmosObject headFile(String path); + @Named("GetObjectMetadata") + @HEAD + @ResponseParser(ParseObjectFromHeadersAndHttpContent.class) + @Fallback(NullOnNotFoundOr404.class) + @Path("/{path}") + @Consumes(MediaType.WILDCARD) + AtmosObject headFile(@PathParam("path") String path); - SystemMetadata getSystemMetadata(String path); + @Named("GetSystemMetadata") + @HEAD + @ResponseParser(ParseSystemMetadataFromHeaders.class) + @Fallback(NullOnNotFoundOr404.class) + // currently throws 403 errors @QueryParams(keys = "metadata/system") + @Path("/{path}") + @Consumes(MediaType.WILDCARD) + SystemMetadata getSystemMetadata(@PathParam("path") String path); - UserMetadata getUserMetadata(String path); + @Named("GetUserMetadata") + @HEAD + @ResponseParser(ParseUserMetadataFromHeaders.class) + @Fallback(NullOnNotFoundOr404.class) + @Path("/{path}") + @QueryParams(keys = "metadata/user") + @Consumes(MediaType.WILDCARD) + UserMetadata getUserMetadata(@PathParam("path") String path); - void deletePath(String path); + @Named("DeleteObject") + @DELETE + @Fallback(TrueOn404FalseOnPathNotEmpty.class) + @Path("/{path}") + @Consumes(MediaType.WILDCARD) + boolean deletePath(@PathParam("path") String path); - boolean pathExists(String path); + @Named("GetObjectMetadata") + @HEAD + @Fallback(FalseOnNotFoundOr404.class) + @Path("/{path}") + @Consumes(MediaType.WILDCARD) + boolean pathExists(@PathParam("path") String path); - boolean isPublic(String path); + @Named("GetObjectMetadata") + @HEAD + @ResponseParser(ReturnTrueIfGroupACLIsOtherRead.class) + @Path("/{path}") + @Consumes(MediaType.WILDCARD) + @Fallback(FalseOnNotFoundOr404.class) + boolean isPublic(@PathParam("path") String path); } diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosAsyncBlobStore.java b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosAsyncBlobStore.java deleted file mode 100644 index 983f0687b5..0000000000 --- a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosAsyncBlobStore.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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.atmos.blobstore; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.util.concurrent.Futures.transform; -import static org.jclouds.atmos.options.PutOptions.Builder.publicRead; - -import java.net.URI; -import java.util.Set; -import java.util.concurrent.Callable; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Provider; -import javax.inject.Singleton; - -import org.jclouds.Constants; -import org.jclouds.atmos.AtmosAsyncClient; -import org.jclouds.atmos.AtmosClient; -import org.jclouds.atmos.blobstore.functions.BlobStoreListOptionsToListOptions; -import org.jclouds.atmos.blobstore.functions.BlobToObject; -import org.jclouds.atmos.blobstore.functions.DirectoryEntryListToResourceMetadataList; -import org.jclouds.atmos.blobstore.functions.ObjectToBlob; -import org.jclouds.atmos.blobstore.functions.ObjectToBlobMetadata; -import org.jclouds.atmos.domain.AtmosObject; -import org.jclouds.atmos.domain.BoundedSet; -import org.jclouds.atmos.domain.DirectoryEntry; -import org.jclouds.atmos.options.ListOptions; -import org.jclouds.atmos.util.AtmosUtils; -import org.jclouds.blobstore.BlobStoreContext; -import org.jclouds.blobstore.domain.Blob; -import org.jclouds.blobstore.domain.BlobMetadata; -import org.jclouds.blobstore.domain.PageSet; -import org.jclouds.blobstore.domain.StorageMetadata; -import org.jclouds.blobstore.functions.BlobToHttpGetOptions; -import org.jclouds.blobstore.internal.BaseAsyncBlobStore; -import org.jclouds.blobstore.options.CreateContainerOptions; -import org.jclouds.blobstore.options.PutOptions; -import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; -import org.jclouds.blobstore.util.BlobUtils; -import org.jclouds.collect.Memoized; -import org.jclouds.crypto.Crypto; -import org.jclouds.domain.Location; -import org.jclouds.http.options.GetOptions; - -import com.google.common.base.Function; -import com.google.common.base.Functions; -import com.google.common.base.Supplier; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; - -/** - * @deprecated will be removed in jclouds 1.7, as async interfaces are no longer - * supported. Please use {@link AtmosBlobStore} - */ -@Deprecated -@Singleton -public class AtmosAsyncBlobStore extends BaseAsyncBlobStore { - private final AtmosAsyncClient async; - private final AtmosClient sync; - private final ObjectToBlob object2Blob; - private final ObjectToBlobMetadata object2BlobMd; - private final BlobToObject blob2Object; - private final BlobStoreListOptionsToListOptions container2ContainerListOptions; - private final DirectoryEntryListToResourceMetadataList container2ResourceList; - private final Crypto crypto; - private final BlobToHttpGetOptions blob2ObjectGetOptions; - private final Provider fetchBlobMetadataProvider; - private final LoadingCache isPublic; - - @Inject - AtmosAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils, - @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier defaultLocation, - @Memoized Supplier> locations, AtmosAsyncClient async, AtmosClient sync, - ObjectToBlob object2Blob, ObjectToBlobMetadata object2BlobMd, BlobToObject blob2Object, - BlobStoreListOptionsToListOptions container2ContainerListOptions, - DirectoryEntryListToResourceMetadataList container2ResourceList, Crypto crypto, - BlobToHttpGetOptions blob2ObjectGetOptions, Provider fetchBlobMetadataProvider, - LoadingCache isPublic) { - super(context, blobUtils, userExecutor, defaultLocation, locations); - this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions"); - this.sync = checkNotNull(sync, "sync"); - this.async = checkNotNull(async, "async"); - this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions, - "container2ContainerListOptions"); - this.container2ResourceList = checkNotNull(container2ResourceList, "container2ResourceList"); - this.object2Blob = checkNotNull(object2Blob, "object2Blob"); - this.blob2Object = checkNotNull(blob2Object, "blob2Object"); - this.object2BlobMd = checkNotNull(object2BlobMd, "object2BlobMd"); - this.crypto = checkNotNull(crypto, "crypto"); - this.fetchBlobMetadataProvider = checkNotNull(fetchBlobMetadataProvider, "fetchBlobMetadataProvider"); - this.isPublic = checkNotNull(isPublic, "isPublic"); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#headFile} - */ - @Override - public ListenableFuture blobMetadata(String container, String key) { - return transform(async.headFile(container + "/" + key), new Function() { - @Override - public BlobMetadata apply(AtmosObject from) { - return object2BlobMd.apply(from); - } - }, userExecutor); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#createDirectory} - *

- * Note location is ignored - */ - @Override - public ListenableFuture createContainerInLocation(Location location, String container) { - return transform(async.createDirectory(container), new Function() { - public Boolean apply(URI from) { - return from != null; - } - }, userExecutor); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#createDirectory} - */ - @Override - public ListenableFuture createDirectory(String container, String directory) { - return transform(async.createDirectory(container + "/" + directory), new Function() { - public Void apply(URI from) { - return null;// no etag - } - }, userExecutor); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#deletePath} followed by - * {@link AtmosAsyncClient#pathExists} until it is true. - */ - protected boolean deleteAndVerifyContainerGone(final String container) { - sync.deletePath(container + "/"); - return !sync.pathExists(container + "/"); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#pathExists} - */ - @Override - public ListenableFuture containerExists(String container) { - return async.pathExists(container + "/"); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#pathExists} - */ - @Override - public ListenableFuture directoryExists(String container, String directory) { - return async.pathExists(container + "/" + directory + "/"); - } - - /** - * This implementation invokes {@link #removeBlob} - */ - @Override - public ListenableFuture deleteDirectory(String containerName, String directory) { - return removeBlob(containerName, directory + "/"); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#pathExists} - * - * @param container - * container - * @param key - * file name - */ - @Override - public ListenableFuture blobExists(String container, String key) { - return async.pathExists(container + "/" + key); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#readFile} - */ - @Override - public ListenableFuture getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) { - GetOptions httpOptions = blob2ObjectGetOptions.apply(options); - ListenableFuture returnVal = async.readFile(container + "/" + key, httpOptions); - return transform(returnVal, object2Blob, userExecutor); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#listDirectories} - */ - @Override - public ListenableFuture> list() { - return transform(async.listDirectories(), container2ResourceList, userExecutor); - } - - /** - * This implementation invokes {@link AtmosAsyncClient#listDirectory} - */ - @Override - public ListenableFuture> list(String container, - org.jclouds.blobstore.options.ListContainerOptions options) { - container = AtmosUtils.adjustContainerIfDirOptionPresent(container, options); - ListOptions nativeOptions = container2ContainerListOptions.apply(options); - ListenableFuture> returnVal = async.listDirectory(container, nativeOptions); - ListenableFuture> list = transform(returnVal, container2ResourceList, - userExecutor); - return options.isDetailed() ? transform(list, - fetchBlobMetadataProvider.get().setContainerName(container)) : list; - } - - /** - * This implementation invokes {@link AtmosAsyncClient#createFile} - *

- * Since there is no etag support in atmos, we just return the path. - */ - @Override - public ListenableFuture putBlob(final String container, final Blob blob) { - final org.jclouds.atmos.options.PutOptions options = new org.jclouds.atmos.options.PutOptions(); - try { - if (isPublic.getUnchecked(container + "/")) - options.publicRead(); - } catch (CacheLoader.InvalidCacheLoadException e) { - // nulls not permitted - } - return userExecutor.submit(new Callable() { - - @Override - public String call() throws Exception { - return AtmosUtils.putBlob(sync, crypto, blob2Object, container, blob, options); - } - - @Override - public String toString() { - return "putBlob(" + container + "," + blob.getMetadata().getName() + ")"; - } - }); - - } - - /** - * This implementation invokes {@link AtmosAsyncClient#deletePath} - */ - @Override - public ListenableFuture removeBlob(String container, String key) { - return Futures.transform(async.deletePath(container + "/" + key), Functions.constant((Void) null), - userExecutor); - } - - @Override - public ListenableFuture putBlob(String container, Blob blob, PutOptions options) { - // TODO implement options - return putBlob(container, blob); - } - - @Override - public ListenableFuture createContainerInLocation(Location location, String container, - CreateContainerOptions options) { - if (options.isPublicRead()) - return transform(async.createDirectory(container, publicRead()), new Function() { - - public Boolean apply(URI from) { - return from != null; - } - - }, userExecutor); - return createContainerInLocation(location, container); - } - -} diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSigner.java b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSigner.java index c3e81722d5..8563222428 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSigner.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSigner.java @@ -23,7 +23,7 @@ import static org.jclouds.reflect.Reflection2.method; import javax.inject.Inject; import javax.inject.Singleton; -import org.jclouds.atmos.AtmosAsyncClient; +import org.jclouds.atmos.AtmosClient; import org.jclouds.atmos.blobstore.functions.BlobToObject; import org.jclouds.atmos.domain.AtmosObject; import org.jclouds.atmos.options.PutOptions; @@ -54,9 +54,9 @@ public class AtmosBlobRequestSigner implements BlobRequestSigner { this.processor = checkNotNull(processor, "processor"); this.blobToObject = checkNotNull(blobToObject, "blobToObject"); this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions"); - this.getMethod = method(AtmosAsyncClient.class, "readFile", String.class, GetOptions[].class); - this.deleteMethod = method(AtmosAsyncClient.class, "deletePath", String.class); - this.createMethod = method(AtmosAsyncClient.class, "createFile", String.class, AtmosObject.class, PutOptions[].class); + this.getMethod = method(AtmosClient.class, "readFile", String.class, GetOptions[].class); + this.deleteMethod = method(AtmosClient.class, "deletePath", String.class); + this.createMethod = method(AtmosClient.class, "createFile", String.class, AtmosObject.class, PutOptions[].class); } @Override diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/config/AtmosBlobStoreContextModule.java b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/config/AtmosBlobStoreContextModule.java index 8cf13d3f78..a562ed64d3 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/config/AtmosBlobStoreContextModule.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/config/AtmosBlobStoreContextModule.java @@ -21,13 +21,13 @@ import java.util.concurrent.TimeUnit; import javax.inject.Singleton; import org.jclouds.atmos.AtmosClient; -import org.jclouds.atmos.blobstore.AtmosAsyncBlobStore; import org.jclouds.atmos.blobstore.AtmosBlobRequestSigner; import org.jclouds.atmos.blobstore.AtmosBlobStore; import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.BlobRequestSigner; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.attr.ConsistencyModel; +import org.jclouds.blobstore.internal.SubmissionAsyncBlobStore; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; @@ -36,15 +36,12 @@ import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.Scopes; -/** - * Configures the {@link AtmosBlobStoreContext}; requires {@link AtmosAsyncBlobStore} bound. - */ public class AtmosBlobStoreContextModule extends AbstractModule { @Override protected void configure() { bind(ConsistencyModel.class).toInstance(ConsistencyModel.EVENTUAL); - bind(AsyncBlobStore.class).to(AtmosAsyncBlobStore.class).in(Scopes.SINGLETON); + bind(AsyncBlobStore.class).to(SubmissionAsyncBlobStore.class).in(Scopes.SINGLETON); bind(BlobStore.class).to(AtmosBlobStore.class).in(Scopes.SINGLETON); bind(BlobRequestSigner.class).to(AtmosBlobRequestSigner.class); } diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosRestClientModule.java b/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosHttpApiModule.java similarity index 92% rename from apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosRestClientModule.java rename to apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosHttpApiModule.java index c1184508c6..af21f9b328 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosRestClientModule.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosHttpApiModule.java @@ -22,7 +22,6 @@ import java.util.concurrent.TimeUnit; import javax.inject.Named; import org.jclouds.Constants; -import org.jclouds.atmos.AtmosAsyncClient; import org.jclouds.atmos.AtmosClient; import org.jclouds.atmos.handlers.AtmosClientErrorRetryHandler; import org.jclouds.atmos.handlers.AtmosServerErrorRetryHandler; @@ -34,8 +33,8 @@ import org.jclouds.http.HttpRetryHandler; import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.ServerError; -import org.jclouds.rest.ConfiguresRestClient; -import org.jclouds.rest.config.RestClientModule; +import org.jclouds.rest.ConfiguresHttpApi; +import org.jclouds.rest.config.HttpApiModule; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; @@ -45,8 +44,8 @@ import com.google.inject.Provides; * Configures the EMC Atmos Online Storage authentication service connection, including logging and * http transport. */ -@ConfiguresRestClient -public class AtmosRestClientModule extends RestClientModule { +@ConfiguresHttpApi +public class AtmosHttpApiModule extends HttpApiModule { @Override protected void configure() { diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientLiveTest.java b/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientLiveTest.java index 9f57ddb752..0ba9a370eb 100644 --- a/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientLiveTest.java +++ b/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientLiveTest.java @@ -63,7 +63,7 @@ public class AtmosClientLiveTest extends BaseBlobStoreIntegrationTest { } public AtmosClient getApi() { - return view.unwrap(AtmosApiMetadata.CONTEXT_TOKEN).getApi(); + return view.unwrapApi(AtmosClient.class); } private static final class HeadMatches implements Runnable { diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/AtmosAsyncClientTest.java b/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientTest.java similarity index 87% rename from apis/atmos/src/test/java/org/jclouds/atmos/AtmosAsyncClientTest.java rename to apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientTest.java index 7dc22973f1..7fa5d4f543 100644 --- a/apis/atmos/src/test/java/org/jclouds/atmos/AtmosAsyncClientTest.java +++ b/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientTest.java @@ -25,7 +25,7 @@ import org.jclouds.Fallbacks.FalseOnNotFoundOr404; import org.jclouds.Fallbacks.NullOnNotFoundOr404; import org.jclouds.apis.ApiMetadata; import org.jclouds.atmos.blobstore.functions.BlobToObject; -import org.jclouds.atmos.config.AtmosRestClientModule; +import org.jclouds.atmos.config.AtmosHttpApiModule; import org.jclouds.atmos.domain.AtmosObject; import org.jclouds.atmos.fallbacks.TrueOn404FalseOnPathNotEmpty; import org.jclouds.atmos.filters.SignRequest; @@ -46,7 +46,7 @@ import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x; import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.options.GetOptions; -import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.ConfiguresHttpApi; import org.jclouds.rest.internal.BaseAsyncClientTest; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.testng.annotations.BeforeClass; @@ -57,17 +57,14 @@ import com.google.common.collect.ImmutableList; import com.google.common.net.HttpHeaders; import com.google.common.reflect.Invokable; import com.google.inject.Module; -/** - * Tests behavior of {@code AtmosAsyncClient} - */ -// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire -@Test(groups = "unit", testName = "AtmosAsyncClientTest") -public class AtmosAsyncClientTest extends BaseAsyncClientTest { + +@Test(groups = "unit", testName = "AtmosClientTest") +public class AtmosClientTest extends BaseAsyncClientTest { private BlobToObject blobToObject; public void testListDirectories() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "listDirectories", ListOptions[].class); + Invokable method = method(AtmosClient.class, "listDirectories", ListOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of()); assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/ HTTP/1.1"); @@ -82,7 +79,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testListDirectory() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "listDirectory", String.class, ListOptions[].class); + Invokable method = method(AtmosClient.class, "listDirectory", String.class, ListOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("directory")); assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/directory/ HTTP/1.1"); @@ -97,7 +94,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testListDirectoriesOptions() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "listDirectories", ListOptions[].class); + Invokable method = method(AtmosClient.class, "listDirectories", ListOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of(new ListOptions().limit(1).token("asda"))); assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/ HTTP/1.1"); @@ -112,7 +109,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testListDirectoryOptions() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "listDirectory", String.class, ListOptions[].class); + Invokable method = method(AtmosClient.class, "listDirectory", String.class, ListOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("directory", new ListOptions().limit(1).token("asda"))); assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/directory/ HTTP/1.1"); @@ -127,7 +124,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testCreateDirectory() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "createDirectory", String.class, PutOptions[].class); + Invokable method = method(AtmosClient.class, "createDirectory", String.class, PutOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir")); assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/ HTTP/1.1"); @@ -142,7 +139,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testCreateDirectoryOptions() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "createDirectory", String.class, PutOptions[].class); + Invokable method = method(AtmosClient.class, "createDirectory", String.class, PutOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir", PutOptions.Builder.publicRead())); assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/ HTTP/1.1"); @@ -158,7 +155,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testCreateFile() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "createFile", String.class, AtmosObject.class, + Invokable method = method(AtmosClient.class, "createFile", String.class, AtmosObject.class, PutOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir", blobToObject .apply(BindBlobToMultipartFormTest.TEST_BLOB))); @@ -175,7 +172,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testCreateFileOptions() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "createFile", String.class, AtmosObject.class, + Invokable method = method(AtmosClient.class, "createFile", String.class, AtmosObject.class, PutOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir", blobToObject .apply(BindBlobToMultipartFormTest.TEST_BLOB), PutOptions.Builder.publicRead())); @@ -193,7 +190,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testUpdateFile() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "updateFile", String.class, AtmosObject.class, + Invokable method = method(AtmosClient.class, "updateFile", String.class, AtmosObject.class, PutOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir", blobToObject .apply(BindBlobToMultipartFormTest.TEST_BLOB))); @@ -210,7 +207,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testUpdateFileOptions() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "updateFile", String.class, AtmosObject.class, + Invokable method = method(AtmosClient.class, "updateFile", String.class, AtmosObject.class, PutOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir", blobToObject .apply(BindBlobToMultipartFormTest.TEST_BLOB), PutOptions.Builder.publicRead())); @@ -228,7 +225,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testReadFile() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "readFile", String.class, GetOptions[].class); + Invokable method = method(AtmosClient.class, "readFile", String.class, GetOptions[].class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir/file")); assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1"); @@ -243,7 +240,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testGetSystemMetadata() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "getSystemMetadata", String.class); + Invokable method = method(AtmosClient.class, "getSystemMetadata", String.class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir/file")); assertRequestLineEquals(request, "HEAD https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1"); @@ -258,7 +255,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testDeletePath() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "deletePath", String.class); + Invokable method = method(AtmosClient.class, "deletePath", String.class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir/file")); assertRequestLineEquals(request, "DELETE https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1"); @@ -273,7 +270,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testIsPublic() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "isPublic", String.class); + Invokable method = method(AtmosClient.class, "isPublic", String.class); GeneratedHttpRequest request = processor.createRequest(method, ImmutableList. of("dir/file")); assertRequestLineEquals(request, "HEAD https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1"); @@ -288,7 +285,7 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest } public void testNewObject() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(AtmosAsyncClient.class, "newObject"); + Invokable method = method(AtmosClient.class, "newObject"); assertEquals(method.getReturnType().getRawType(), AtmosObject.class); } @@ -307,11 +304,11 @@ public class AtmosAsyncClientTest extends BaseAsyncClientTest @Override protected Module createModule() { - return new TestAtmosRestClientModule(); + return new TestAtmosHttpApiModule(); } - @ConfiguresRestClient - private static final class TestAtmosRestClientModule extends AtmosRestClientModule { + @ConfiguresHttpApi + private static final class TestAtmosHttpApiModule extends AtmosHttpApiModule { @Override protected void configure() { super.configure(); diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSignerTest.java b/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSignerTest.java index d6620b5df3..b973e53ea4 100644 --- a/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSignerTest.java +++ b/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSignerTest.java @@ -23,15 +23,15 @@ import java.util.Date; import org.jclouds.apis.ApiMetadata; import org.jclouds.atmos.AtmosApiMetadata; -import org.jclouds.atmos.AtmosAsyncClient; -import org.jclouds.atmos.config.AtmosRestClientModule; +import org.jclouds.atmos.AtmosClient; +import org.jclouds.atmos.config.AtmosHttpApiModule; import org.jclouds.atmos.filters.SignRequest; import org.jclouds.blobstore.BlobRequestSigner; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob.Factory; import org.jclouds.date.TimeStamp; import org.jclouds.http.HttpRequest; -import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.ConfiguresHttpApi; import org.jclouds.rest.internal.BaseAsyncClientTest; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -44,7 +44,7 @@ import com.google.inject.Module; */ // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire @Test(groups = "unit", testName = "AtmosBlobRequestSignerTest") -public class AtmosBlobRequestSignerTest extends BaseAsyncClientTest { +public class AtmosBlobRequestSignerTest extends BaseAsyncClientTest { public AtmosBlobRequestSignerTest() { // this is base64 decoded in the signer; @@ -124,11 +124,11 @@ public class AtmosBlobRequestSignerTest extends BaseAsyncClientTest of(new MockModule(), new TestAtmosRestClientModule(), new NullLoggingModule())) + ImmutableSet. of(new MockModule(), new TestAtmosHttpApiModule(), new NullLoggingModule())) .buildInjector(); filter = injector.getInstance(SignRequest.class); } - @ConfiguresRestClient - private static final class TestAtmosRestClientModule extends AtmosRestClientModule { + @ConfiguresHttpApi + private static final class TestAtmosHttpApiModule extends AtmosHttpApiModule { @Override protected void configure() { diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/internal/StubAtmosAsyncClient.java b/apis/atmos/src/test/java/org/jclouds/atmos/internal/StubAtmosAsyncClient.java deleted file mode 100644 index 211d0a489b..0000000000 --- a/apis/atmos/src/test/java/org/jclouds/atmos/internal/StubAtmosAsyncClient.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * 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.atmos.internal; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.util.concurrent.Futures.immediateFailedFuture; -import static com.google.common.util.concurrent.Futures.immediateFuture; - -import java.io.IOException; -import java.net.URI; -import java.util.concurrent.ExecutionException; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.jclouds.Constants; -import org.jclouds.atmos.AtmosAsyncClient; -import org.jclouds.atmos.blobstore.functions.BlobMetadataToObject; -import org.jclouds.atmos.blobstore.functions.BlobToObject; -import org.jclouds.atmos.blobstore.functions.ListOptionsToBlobStoreListOptions; -import org.jclouds.atmos.blobstore.functions.ObjectToBlob; -import org.jclouds.atmos.blobstore.functions.ResourceMetadataListToDirectoryEntryList; -import org.jclouds.atmos.domain.AtmosObject; -import org.jclouds.atmos.domain.BoundedSet; -import org.jclouds.atmos.domain.DirectoryEntry; -import org.jclouds.atmos.domain.SystemMetadata; -import org.jclouds.atmos.domain.UserMetadata; -import org.jclouds.atmos.options.ListOptions; -import org.jclouds.atmos.options.PutOptions; -import org.jclouds.blobstore.LocalAsyncBlobStore; -import org.jclouds.blobstore.domain.Blob; -import org.jclouds.blobstore.domain.BlobMetadata; -import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; -import org.jclouds.http.options.GetOptions; -import org.jclouds.lifecycle.Closer; - -import com.google.common.base.Function; -import com.google.common.base.Functions; -import com.google.common.base.Throwables; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; - -/** - * Implementation of {@link AtmosAsyncClient} which keeps all data in a local Map object. - */ -public class StubAtmosAsyncClient implements AtmosAsyncClient { - private final HttpGetOptionsListToGetOptions httpGetOptionsConverter; - private final LocalAsyncBlobStore blobStore; - private final AtmosObject.Factory objectProvider; - private final ObjectToBlob object2Blob; - private final BlobToObject blob2Object; - private final BlobMetadataToObject blob2ObjectInfo; - private final ListOptionsToBlobStoreListOptions container2ContainerListOptions; - private final ResourceMetadataListToDirectoryEntryList resource2ObjectList; - private final ListeningExecutorService userExecutor; - private final Closer closer; - - @Inject - private StubAtmosAsyncClient(LocalAsyncBlobStore blobStore, AtmosObject.Factory objectProvider, - HttpGetOptionsListToGetOptions httpGetOptionsConverter, ObjectToBlob object2Blob, BlobToObject blob2Object, - BlobMetadataToObject blob2ObjectInfo, ListOptionsToBlobStoreListOptions container2ContainerListOptions, - @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, - ResourceMetadataListToDirectoryEntryList resource2ContainerList, Closer closer) { - this.blobStore = blobStore; - this.objectProvider = objectProvider; - this.httpGetOptionsConverter = httpGetOptionsConverter; - this.object2Blob = checkNotNull(object2Blob, "object2Blob"); - this.blob2Object = checkNotNull(blob2Object, "blob2Object"); - this.blob2ObjectInfo = checkNotNull(blob2ObjectInfo, "blob2ObjectInfo"); - this.container2ContainerListOptions = checkNotNull(container2ContainerListOptions, - "container2ContainerListOptions"); - this.resource2ObjectList = checkNotNull(resource2ContainerList, "resource2ContainerList"); - this.userExecutor = userExecutor; - this.closer = checkNotNull(closer, "closer"); - } - - @Override - public ListenableFuture createDirectory(String directoryName, PutOptions... options) { - final String container; - final String path; - if (directoryName.indexOf('/') != -1) { - container = directoryName.substring(0, directoryName.indexOf('/')); - path = directoryName.substring(directoryName.indexOf('/') + 1); - } else { - container = directoryName; - path = null; - } - return Futures.transform(blobStore.createContainerInLocation(null, container), new Function() { - - public URI apply(Boolean from) { - if (path != null) { - Blob blob = blobStore.blobBuilder(path + "/").payload("").contentType("application/directory").build(); - blobStore.putBlob(container, blob); - } - return URI.create("http://stub/containers/" + container); - } - - }, userExecutor); - } - - @Override - public ListenableFuture createFile(String parent, AtmosObject object, PutOptions... options) { - final String uri = "http://stub/containers/" + parent + "/" + object.getContentMetadata().getName(); - String file = object.getContentMetadata().getName(); - String container = parent; - if (parent.indexOf('/') != -1) { - container = parent.substring(0, parent.indexOf('/')); - String path = parent.substring(parent.indexOf('/') + 1); - if (!path.equals("")) - object.getContentMetadata().setName(path + "/" + file); - } - Blob blob = object2Blob.apply(object); - return Futures.transform(blobStore.putBlob(container, blob), new Function() { - - public URI apply(String from) { - return URI.create(uri); - } - - }, userExecutor); - } - - @Override - public ListenableFuture deletePath(String path) { - if (path.indexOf('/') == path.length() - 1) { - // chop off the trailing slash - return blobStore.deleteContainerIfEmpty(path.substring(0, path.length() - 1)); - } else { - String container = path.substring(0, path.indexOf('/')); - path = path.substring(path.indexOf('/') + 1); - return Futures.transform(blobStore.removeBlob(container, path), Functions.constant(Boolean.TRUE), userExecutor); - } - } - - @Override - public ListenableFuture getSystemMetadata(String path) { - throw new UnsupportedOperationException(); - } - - @Override - public ListenableFuture 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 Futures.transform(blobStore.blobMetadata(container, path), new Function() { - public UserMetadata apply(BlobMetadata from) { - return blob2ObjectInfo.apply(from).getUserMetadata(); - } - }, userExecutor); - } - } - - @Override - public ListenableFuture headFile(String path) { - String container = path.substring(0, path.indexOf('/')); - path = path.substring(path.indexOf('/') + 1); - try { - return Futures.transform(blobStore.getBlob(container, path), blob2Object, userExecutor); - } catch (Exception e) { - return immediateFailedFuture(Throwables.getRootCause(e)); - } - } - - @Override - public ListenableFuture> listDirectories(ListOptions... optionsList) { - // org.jclouds.blobstore.options.ListOptions options = container2ContainerListOptions - // .apply(optionsList); - return Futures.transform(blobStore.list(), resource2ObjectList, userExecutor); - } - - @Override - public ListenableFuture> listDirectory(String directoryName, - ListOptions... optionsList) { - org.jclouds.blobstore.options.ListContainerOptions options = container2ContainerListOptions.apply(optionsList); - String container = directoryName; - if (directoryName.indexOf('/') != -1) { - container = directoryName.substring(0, directoryName.indexOf('/')); - String path = directoryName.substring(directoryName.indexOf('/') + 1); - if (!path.equals("")) - options.inDirectory(path); - } - return Futures.transform(blobStore.list(container, options), resource2ObjectList, userExecutor); - } - - @Override - public AtmosObject newObject() { - return this.objectProvider.create(null); - } - - @Override - public ListenableFuture pathExists(final String path) { - if (path.indexOf('/') == path.length() - 1) { - // chop off the trailing slash - return blobStore.containerExists(path.substring(0, path.length() - 1)); - } else { - String container = path.substring(0, path.indexOf('/')); - String blobName = path.substring(path.indexOf('/') + 1); - try { - return immediateFuture(blobStore.blobMetadata(container, blobName).get() != null); - } catch (InterruptedException e) { - return immediateFailedFuture(e); - } catch (ExecutionException e) { - return immediateFailedFuture(e); - } - } - } - - @Override - public ListenableFuture readFile(String path, GetOptions... options) { - String container = path.substring(0, path.indexOf('/')); - String blobName = path.substring(path.indexOf('/') + 1); - org.jclouds.blobstore.options.GetOptions getOptions = httpGetOptionsConverter.apply(options); - return Futures.transform(blobStore.getBlob(container, blobName, getOptions), blob2Object, userExecutor); - } - - @Override - public ListenableFuture updateFile(String parent, AtmosObject object, PutOptions... options) { - throw new UnsupportedOperationException(); - } - - @Override - public ListenableFuture isPublic(String path) { - throw new UnsupportedOperationException(); - } - - @Override - public void close() throws IOException { - closer.close(); - } -}