You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ad...@apache.org on 2014/10/04 07:07:15 UTC

[2/2] git commit: JCLOUDS-40 unasync atmos.

JCLOUDS-40 unasync atmos.


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/9b71a9dc
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/9b71a9dc
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/9b71a9dc

Branch: refs/heads/master
Commit: 9b71a9dcb8f5361cdcfb671f6bacbe757ec6dfc8
Parents: 9df0cd2
Author: Adrian Cole <ac...@twitter.com>
Authored: Fri Oct 3 21:38:57 2014 -0700
Committer: Adrian Cole <ad...@apache.org>
Committed: Fri Oct 3 22:06:12 2014 -0700

----------------------------------------------------------------------
 apis/atmos/pom.xml                              |   1 -
 .../org/jclouds/atmos/AtmosApiMetadata.java     |  26 +-
 .../org/jclouds/atmos/AtmosAsyncClient.java     | 230 -------------
 .../java/org/jclouds/atmos/AtmosClient.java     | 165 +++++++--
 .../atmos/blobstore/AtmosAsyncBlobStore.java    | 289 ----------------
 .../atmos/blobstore/AtmosBlobRequestSigner.java |   8 +-
 .../config/AtmosBlobStoreContextModule.java     |   7 +-
 .../atmos/config/AtmosHttpApiModule.java        |  96 ++++++
 .../atmos/config/AtmosRestClientModule.java     |  97 ------
 .../org/jclouds/atmos/AtmosAsyncClientTest.java | 333 -------------------
 .../org/jclouds/atmos/AtmosClientLiveTest.java  |   2 +-
 .../java/org/jclouds/atmos/AtmosClientTest.java | 330 ++++++++++++++++++
 .../blobstore/AtmosBlobRequestSignerTest.java   |  14 +-
 .../jclouds/atmos/filters/SignRequestTest.java  |  10 +-
 .../atmos/internal/StubAtmosAsyncClient.java    | 246 --------------
 15 files changed, 587 insertions(+), 1267 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/pom.xml
----------------------------------------------------------------------
diff --git a/apis/atmos/pom.xml b/apis/atmos/pom.xml
index f6830e5..57ee14e 100644
--- a/apis/atmos/pom.xml
+++ b/apis/atmos/pom.xml
@@ -91,7 +91,6 @@
                 </goals>
                 <configuration>
                   <systemPropertyVariables>
-                    <test.initializer>${test.initializer}</test.initializer>
                     <jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
                     <jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
                     <test.atmos.endpoint>${test.atmos.endpoint}</test.atmos.endpoint>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/main/java/org/jclouds/atmos/AtmosApiMetadata.java
----------------------------------------------------------------------
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 874f6e1..109ef1f 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<org.jclouds.rest.RestContext<AtmosClient, AtmosAsyncClient>> CONTEXT_TOKEN = new TypeToken<org.jclouds.rest.RestContext<AtmosClient, AtmosAsyncClient>>() {
-      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<Builder> {
-      @SuppressWarnings("deprecation")
+   public static class Builder extends BaseHttpApiMetadata.Builder<AtmosClient, 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.<Class<? extends Module>>of(AtmosRestClientModule.class, AtmosBlobStoreContextModule.class));
+         .defaultModules(ImmutableSet.<Class<? extends Module>>of(AtmosHttpApiModule.class, AtmosBlobStoreContextModule.class));
       }
 
       @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/main/java/org/jclouds/atmos/AtmosAsyncClient.java
----------------------------------------------------------------------
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 5334487..0000000
--- 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.
- * <p/>
- * 
- * @see AtmosClient
- * @see <a href="https://community.emc.com/community/labs/atmos_online" />
- * 
- * @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<BoundedSet<? extends DirectoryEntry>> listDirectories(ListOptions... options);
-
-   /**
-    * @see AtmosClient#listDirectory
-    */
-   @Named("ListDirectory")
-   @GET
-   @Path("/{directoryName}/")
-   @ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
-   @Fallback(ThrowContainerNotFoundOn404.class)
-   @Consumes(MediaType.TEXT_XML)
-   ListenableFuture<BoundedSet<? extends DirectoryEntry>> 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<URI> 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<URI> 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<Void> 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<AtmosObject> 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<AtmosObject> 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<SystemMetadata> 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<UserMetadata> getUserMetadata(@PathParam("path") String path);
-
-   /**
-    * @see AtmosClient#deletePath
-    */
-   @Named("DeleteObject")
-   @DELETE
-   @Fallback(TrueOn404FalseOnPathNotEmpty.class)
-   @Path("/{path}")
-   @Consumes(MediaType.WILDCARD)
-   ListenableFuture<Boolean> deletePath(@PathParam("path") String path);
-
-   /**
-    * @see AtmosClient#pathExists
-    */
-   @Named("GetObjectMetadata")
-   @HEAD
-   @Fallback(FalseOnNotFoundOr404.class)
-   @Path("/{path}")
-   @Consumes(MediaType.WILDCARD)
-   ListenableFuture<Boolean> pathExists(@PathParam("path") String path);
-
-   /**
-    * @see AtmosClient#isPublic
-    */
-   @Named("GetObjectMetadata")
-   @HEAD
-   @ResponseParser(ReturnTrueIfGroupACLIsOtherRead.class)
-   @Path("/{path}")
-   @Consumes(MediaType.WILDCARD)
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> isPublic(@PathParam("path") String path);
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/main/java/org/jclouds/atmos/AtmosClient.java
----------------------------------------------------------------------
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 38168e2..9d5a5ce 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.
- * <p/>
- * 
- * @see AtmosAsyncClient
- * @see <a href="https://community.emc.com/community/labs/atmos_online" />
- */
+/** 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<? extends DirectoryEntry> listDirectories(ListOptions... options);
 
-   BoundedSet<? extends DirectoryEntry> listDirectory(String directoryName, ListOptions... options);
-
-   URI createDirectory(String directoryName, PutOptions... options);
+   @Named("ListDirectory")
+   @GET
+   @Path("/{directoryName}/")
+   @ResponseParser(ParseDirectoryListFromContentAndHeaders.class)
+   @Fallback(ThrowContainerNotFoundOn404.class)
+   @Consumes(MediaType.TEXT_XML)
+   BoundedSet<? extends DirectoryEntry> listDirectory(
+         @PathParam("directoryName") String directoryName, ListOptions... 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);
-
-   void updateFile(String parent, AtmosObject object, PutOptions... options);
-
-   AtmosObject readFile(String path, GetOptions... options);
-
-   AtmosObject headFile(String path);
-
-   SystemMetadata getSystemMetadata(String path);
-
-   UserMetadata getUserMetadata(String path);
-
-   void deletePath(String path);
-
-   boolean pathExists(String path);
-
-   boolean isPublic(String path);
+   @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);
+
+   @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);
+
+   @Named("ReadObject")
+   @GET
+   @ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Path("/{path}")
+   @Consumes(MediaType.WILDCARD)
+   AtmosObject readFile(@PathParam("path") String path, GetOptions... options);
+
+   @Named("GetObjectMetadata")
+   @HEAD
+   @ResponseParser(ParseObjectFromHeadersAndHttpContent.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Path("/{path}")
+   @Consumes(MediaType.WILDCARD)
+   AtmosObject headFile(@PathParam("path") 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);
+
+   @Named("GetUserMetadata")
+   @HEAD
+   @ResponseParser(ParseUserMetadataFromHeaders.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Path("/{path}")
+   @QueryParams(keys = "metadata/user")
+   @Consumes(MediaType.WILDCARD)
+   UserMetadata getUserMetadata(@PathParam("path") String path);
+
+   @Named("DeleteObject")
+   @DELETE
+   @Fallback(TrueOn404FalseOnPathNotEmpty.class)
+   @Path("/{path}")
+   @Consumes(MediaType.WILDCARD)
+   boolean deletePath(@PathParam("path") String path);
+
+   @Named("GetObjectMetadata")
+   @HEAD
+   @Fallback(FalseOnNotFoundOr404.class)
+   @Path("/{path}")
+   @Consumes(MediaType.WILDCARD)
+   boolean pathExists(@PathParam("path") String path);
+
+   @Named("GetObjectMetadata")
+   @HEAD
+   @ResponseParser(ReturnTrueIfGroupACLIsOtherRead.class)
+   @Path("/{path}")
+   @Consumes(MediaType.WILDCARD)
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean isPublic(@PathParam("path") String path);
 
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosAsyncBlobStore.java
----------------------------------------------------------------------
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 3beec33..0000000
--- 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<FetchBlobMetadata> fetchBlobMetadataProvider;
-   private final LoadingCache<String, Boolean> isPublic;
-
-   @Inject
-   AtmosAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils,
-            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier<Location> defaultLocation,
-            @Memoized Supplier<Set<? extends Location>> locations, AtmosAsyncClient async, AtmosClient sync,
-            ObjectToBlob object2Blob, ObjectToBlobMetadata object2BlobMd, BlobToObject blob2Object,
-            BlobStoreListOptionsToListOptions container2ContainerListOptions,
-            DirectoryEntryListToResourceMetadataList container2ResourceList, Crypto crypto,
-            BlobToHttpGetOptions blob2ObjectGetOptions, Provider<FetchBlobMetadata> fetchBlobMetadataProvider,
-            LoadingCache<String, Boolean> 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> blobMetadata(String container, String key) {
-      return transform(async.headFile(container + "/" + key), new Function<AtmosObject, BlobMetadata>() {
-         @Override
-         public BlobMetadata apply(AtmosObject from) {
-            return object2BlobMd.apply(from);
-         }
-      }, userExecutor);
-   }
-
-   /**
-    * This implementation invokes {@link AtmosAsyncClient#createDirectory}
-    * <p/>
-    * Note location is ignored
-    */
-   @Override
-   public ListenableFuture<Boolean> createContainerInLocation(Location location, String container) {
-      return transform(async.createDirectory(container), new Function<URI, Boolean>() {
-         public Boolean apply(URI from) {
-            return from != null;
-         }
-      }, userExecutor);
-   }
-
-   /**
-    * This implementation invokes {@link AtmosAsyncClient#createDirectory}
-    */
-   @Override
-   public ListenableFuture<Void> createDirectory(String container, String directory) {
-      return transform(async.createDirectory(container + "/" + directory), new Function<URI, Void>() {
-         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<Boolean> containerExists(String container) {
-      return async.pathExists(container + "/");
-   }
-
-   /**
-    * This implementation invokes {@link AtmosAsyncClient#pathExists}
-    */
-   @Override
-   public ListenableFuture<Boolean> directoryExists(String container, String directory) {
-      return async.pathExists(container + "/" + directory + "/");
-   }
-
-   /**
-    * This implementation invokes {@link #removeBlob}
-    */
-   @Override
-   public ListenableFuture<Void> 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<Boolean> blobExists(String container, String key) {
-      return async.pathExists(container + "/" + key);
-   }
-
-   /**
-    * This implementation invokes {@link AtmosAsyncClient#readFile}
-    */
-   @Override
-   public ListenableFuture<Blob> getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) {
-      GetOptions httpOptions = blob2ObjectGetOptions.apply(options);
-      ListenableFuture<AtmosObject> returnVal = async.readFile(container + "/" + key, httpOptions);
-      return transform(returnVal, object2Blob, userExecutor);
-   }
-
-   /**
-    * This implementation invokes {@link AtmosAsyncClient#listDirectories}
-    */
-   @Override
-   public ListenableFuture<PageSet<? extends StorageMetadata>> list() {
-      return transform(async.listDirectories(), container2ResourceList, userExecutor);
-   }
-
-   /**
-    * This implementation invokes {@link AtmosAsyncClient#listDirectory}
-    */
-   @Override
-   public ListenableFuture<PageSet<? extends StorageMetadata>> list(String container,
-            org.jclouds.blobstore.options.ListContainerOptions options) {
-      container = AtmosUtils.adjustContainerIfDirOptionPresent(container, options);
-      ListOptions nativeOptions = container2ContainerListOptions.apply(options);
-      ListenableFuture<BoundedSet<? extends DirectoryEntry>> returnVal = async.listDirectory(container, nativeOptions);
-      ListenableFuture<PageSet<? extends StorageMetadata>> list = transform(returnVal, container2ResourceList,
-            userExecutor);
-      return options.isDetailed() ? transform(list,
-               fetchBlobMetadataProvider.get().setContainerName(container)) : list;
-   }
-
-   /**
-    * This implementation invokes {@link AtmosAsyncClient#createFile}
-    * <p/>
-    * Since there is no etag support in atmos, we just return the path.
-    */
-   @Override
-   public ListenableFuture<String> 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<String>() {
-
-         @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<Void> removeBlob(String container, String key) {
-      return Futures.transform(async.deletePath(container + "/" + key), Functions.constant((Void) null),
-            userExecutor);
-   }
-
-   @Override
-   public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options) {
-      // TODO implement options
-      return putBlob(container, blob);
-   }
-
-   @Override
-   public ListenableFuture<Boolean> createContainerInLocation(Location location, String container,
-            CreateContainerOptions options) {
-      if (options.isPublicRead())
-         return transform(async.createDirectory(container, publicRead()), new Function<URI, Boolean>() {
-
-            public Boolean apply(URI from) {
-               return from != null;
-            }
-
-         }, userExecutor);
-      return createContainerInLocation(location, container);
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSigner.java
----------------------------------------------------------------------
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 c3e8172..8563222 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

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/config/AtmosBlobStoreContextModule.java
----------------------------------------------------------------------
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 8cf13d3..a562ed6 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);
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosHttpApiModule.java
----------------------------------------------------------------------
diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosHttpApiModule.java b/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosHttpApiModule.java
new file mode 100644
index 0000000..af21f9b
--- /dev/null
+++ b/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosHttpApiModule.java
@@ -0,0 +1,96 @@
+/*
+ * 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.config;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Named;
+
+import org.jclouds.Constants;
+import org.jclouds.atmos.AtmosClient;
+import org.jclouds.atmos.handlers.AtmosClientErrorRetryHandler;
+import org.jclouds.atmos.handlers.AtmosServerErrorRetryHandler;
+import org.jclouds.atmos.handlers.ParseAtmosErrorFromXmlContent;
+import org.jclouds.date.DateService;
+import org.jclouds.date.TimeStamp;
+import org.jclouds.http.HttpErrorHandler;
+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.ConfiguresHttpApi;
+import org.jclouds.rest.config.HttpApiModule;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.inject.Provides;
+
+/**
+ * Configures the EMC Atmos Online Storage authentication service connection, including logging and
+ * http transport.
+ */
+@ConfiguresHttpApi
+public class AtmosHttpApiModule extends HttpApiModule<AtmosClient> {
+
+   @Override
+   protected void configure() {
+      install(new AtmosParserModule());
+      install(new AtmosObjectModule());
+      super.configure();
+   }
+
+   @Provides
+   @TimeStamp
+   protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
+      return cache.get();
+   }
+
+   /**
+    * borrowing concurrency code to ensure that caching takes place properly
+    */
+   @Provides
+   @TimeStamp
+   Supplier<String> provideTimeStampCache(@Named(Constants.PROPERTY_SESSION_INTERVAL) long seconds,
+            final DateService dateService) {
+      return Suppliers.memoizeWithExpiration(new Supplier<String>() {
+         public String get() {
+            return dateService.rfc822DateFormat();
+         }
+      }, seconds, TimeUnit.SECONDS);
+   }
+
+   @Provides
+   @TimeStamp
+   protected Long provideShareableUrlTimeout() {
+      return new Date().getTime() + TimeUnit.HOURS.toMillis(1);
+   }
+
+   @Override
+   protected void bindErrorHandlers() {
+      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseAtmosErrorFromXmlContent.class);
+      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseAtmosErrorFromXmlContent.class);
+      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseAtmosErrorFromXmlContent.class);
+   }
+
+   @Override
+   protected void bindRetryHandlers() {
+      bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AtmosClientErrorRetryHandler.class);
+      bind(HttpRetryHandler.class).annotatedWith(ServerError.class).to(AtmosServerErrorRetryHandler.class);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosRestClientModule.java
----------------------------------------------------------------------
diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosRestClientModule.java b/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosRestClientModule.java
deleted file mode 100644
index c118450..0000000
--- a/apis/atmos/src/main/java/org/jclouds/atmos/config/AtmosRestClientModule.java
+++ /dev/null
@@ -1,97 +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.config;
-
-import java.util.Date;
-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;
-import org.jclouds.atmos.handlers.ParseAtmosErrorFromXmlContent;
-import org.jclouds.date.DateService;
-import org.jclouds.date.TimeStamp;
-import org.jclouds.http.HttpErrorHandler;
-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 com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-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<AtmosClient, AtmosAsyncClient> {
-
-   @Override
-   protected void configure() {
-      install(new AtmosParserModule());
-      install(new AtmosObjectModule());
-      super.configure();
-   }
-
-   @Provides
-   @TimeStamp
-   protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
-      return cache.get();
-   }
-
-   /**
-    * borrowing concurrency code to ensure that caching takes place properly
-    */
-   @Provides
-   @TimeStamp
-   Supplier<String> provideTimeStampCache(@Named(Constants.PROPERTY_SESSION_INTERVAL) long seconds,
-            final DateService dateService) {
-      return Suppliers.memoizeWithExpiration(new Supplier<String>() {
-         public String get() {
-            return dateService.rfc822DateFormat();
-         }
-      }, seconds, TimeUnit.SECONDS);
-   }
-
-   @Provides
-   @TimeStamp
-   protected Long provideShareableUrlTimeout() {
-      return new Date().getTime() + TimeUnit.HOURS.toMillis(1);
-   }
-
-   @Override
-   protected void bindErrorHandlers() {
-      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseAtmosErrorFromXmlContent.class);
-      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseAtmosErrorFromXmlContent.class);
-      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseAtmosErrorFromXmlContent.class);
-   }
-
-   @Override
-   protected void bindRetryHandlers() {
-      bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AtmosClientErrorRetryHandler.class);
-      bind(HttpRetryHandler.class).annotatedWith(ServerError.class).to(AtmosServerErrorRetryHandler.class);
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/test/java/org/jclouds/atmos/AtmosAsyncClientTest.java
----------------------------------------------------------------------
diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/AtmosAsyncClientTest.java b/apis/atmos/src/test/java/org/jclouds/atmos/AtmosAsyncClientTest.java
deleted file mode 100644
index 7dc2297..0000000
--- a/apis/atmos/src/test/java/org/jclouds/atmos/AtmosAsyncClientTest.java
+++ /dev/null
@@ -1,333 +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 org.jclouds.reflect.Reflection2.method;
-import static org.testng.Assert.assertEquals;
-
-import java.io.IOException;
-
-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.domain.AtmosObject;
-import org.jclouds.atmos.fallbacks.TrueOn404FalseOnPathNotEmpty;
-import org.jclouds.atmos.filters.SignRequest;
-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.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.blobstore.binders.BindBlobToMultipartFormTest;
-import org.jclouds.date.TimeStamp;
-import org.jclouds.http.HttpRequest;
-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.internal.BaseAsyncClientTest;
-import org.jclouds.rest.internal.GeneratedHttpRequest;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Supplier;
-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<AtmosAsyncClient> {
-
-   private BlobToObject blobToObject;
-
-   public void testListDirectories() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "listDirectories", ListOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of());
-
-      assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": text/xml\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseDirectoryListFromContentAndHeaders.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testListDirectory() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "listDirectory", String.class, ListOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("directory"));
-
-      assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/directory/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": text/xml\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseDirectoryListFromContentAndHeaders.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, ThrowContainerNotFoundOn404.class);
-
-      checkFilters(request);
-   }
-
-   public void testListDirectoriesOptions() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "listDirectories", ListOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of(new ListOptions().limit(1).token("asda")));
-
-      assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": text/xml\nx-emc-limit: 1\nx-emc-token: asda\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseDirectoryListFromContentAndHeaders.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testListDirectoryOptions() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "listDirectory", String.class, ListOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("directory", new ListOptions().limit(1).token("asda")));
-
-      assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/directory/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": text/xml\nx-emc-limit: 1\nx-emc-token: asda\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseDirectoryListFromContentAndHeaders.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, ThrowContainerNotFoundOn404.class);
-
-      checkFilters(request);
-   }
-
-   public void testCreateDirectory() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "createDirectory", String.class, PutOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir"));
-
-      assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
-      assertPayloadEquals(request, "", "application/octet-stream", false);
-
-      assertResponseParserClassEquals(method, request, ParseURIFromListOrLocationHeaderIf20x.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, NullOnKeyAlreadyExists.class);
-
-      checkFilters(request);
-   }
-
-   public void testCreateDirectoryOptions() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "createDirectory", String.class, PutOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", PutOptions.Builder.publicRead()));
-
-      assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/ HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT
-               + ": */*\nx-emc-groupacl: other=READ\nx-emc-useracl: root=FULL_CONTROL\n");
-      assertPayloadEquals(request, "", "application/octet-stream", false);
-
-      assertResponseParserClassEquals(method, request, ParseURIFromListOrLocationHeaderIf20x.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, NullOnKeyAlreadyExists.class);
-
-      checkFilters(request);
-   }
-
-   public void testCreateFile() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "createFile", String.class, AtmosObject.class,
-               PutOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", blobToObject
-               .apply(BindBlobToMultipartFormTest.TEST_BLOB)));
-
-      assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/hello HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\nExpect: 100-continue\n");
-      assertPayloadEquals(request, "hello", "text/plain", false);
-
-      assertResponseParserClassEquals(method, request, ParseNullableURIFromListOrLocationHeaderIf20x.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testCreateFileOptions() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "createFile", String.class, AtmosObject.class,
-               PutOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", blobToObject
-               .apply(BindBlobToMultipartFormTest.TEST_BLOB), PutOptions.Builder.publicRead()));
-
-      assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/hello HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT
-               + ": */*\nExpect: 100-continue\nx-emc-groupacl: other=READ\nx-emc-useracl: root=FULL_CONTROL\n");
-      assertPayloadEquals(request, "hello", "text/plain", false);
-
-      assertResponseParserClassEquals(method, request, ParseNullableURIFromListOrLocationHeaderIf20x.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-
-      checkFilters(request);
-   }
-
-   public void testUpdateFile() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "updateFile", String.class, AtmosObject.class,
-               PutOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", blobToObject
-               .apply(BindBlobToMultipartFormTest.TEST_BLOB)));
-
-      assertRequestLineEquals(request, "PUT https://accesspoint.atmosonline.com/rest/namespace/dir/hello HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\nExpect: 100-continue\n");
-      assertPayloadEquals(request, "hello", "text/plain", false);
-
-      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, ThrowKeyNotFoundOn404.class);
-
-      checkFilters(request);
-   }
-
-   public void testUpdateFileOptions() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "updateFile", String.class, AtmosObject.class,
-               PutOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", blobToObject
-               .apply(BindBlobToMultipartFormTest.TEST_BLOB), PutOptions.Builder.publicRead()));
-
-      assertRequestLineEquals(request, "PUT https://accesspoint.atmosonline.com/rest/namespace/dir/hello HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT
-               + ": */*\nExpect: 100-continue\nx-emc-groupacl: other=READ\nx-emc-useracl: root=FULL_CONTROL\n");
-      assertPayloadEquals(request, "hello", "text/plain", false);
-
-      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, ThrowKeyNotFoundOn404.class);
-
-      checkFilters(request);
-   }
-
-   public void testReadFile() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "readFile", String.class, GetOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir/file"));
-
-      assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseObjectFromHeadersAndHttpContent.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, NullOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-
-   public void testGetSystemMetadata() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "getSystemMetadata", String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir/file"));
-
-      assertRequestLineEquals(request, "HEAD https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseSystemMetadataFromHeaders.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, NullOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-
-   public void testDeletePath() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "deletePath", String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir/file"));
-
-      assertRequestLineEquals(request, "DELETE https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, TrueOn404FalseOnPathNotEmpty.class);
-
-      checkFilters(request);
-   }
-
-   public void testIsPublic() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "isPublic", String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir/file"));
-
-      assertRequestLineEquals(request, "HEAD https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReturnTrueIfGroupACLIsOtherRead.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseOnNotFoundOr404.class);
-
-      checkFilters(request);
-   }
-
-   public void testNewObject() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AtmosAsyncClient.class, "newObject");
-      assertEquals(method.getReturnType().getRawType(), AtmosObject.class);
-   }
-
-   @Override
-   protected void checkFilters(HttpRequest request) {
-      assertEquals(request.getFilters().size(), 1);
-      assertEquals(request.getFilters().get(0).getClass(), SignRequest.class);
-   }
-
-   @BeforeClass
-   @Override
-   protected void setupFactory() throws IOException {
-      super.setupFactory();
-      blobToObject = injector.getInstance(BlobToObject.class);
-   }
-
-   @Override
-   protected Module createModule() {
-      return new TestAtmosRestClientModule();
-   }
-
-      @ConfiguresRestClient
-   private static final class TestAtmosRestClientModule extends AtmosRestClientModule {
-      @Override
-      protected void configure() {
-         super.configure();
-      }
-
-      @Override
-      protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
-         return "Thu, 05 Jun 2008 16:38:19 GMT";
-      }
-   }
-
-   protected String provider = "atmos";
-
-   @Override
-   public ApiMetadata createApiMetadata() {
-      return new AtmosApiMetadata();
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientLiveTest.java
----------------------------------------------------------------------
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 9f57ddb..0ba9a37 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 {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientTest.java
----------------------------------------------------------------------
diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientTest.java b/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientTest.java
new file mode 100644
index 0000000..7fa5d4f
--- /dev/null
+++ b/apis/atmos/src/test/java/org/jclouds/atmos/AtmosClientTest.java
@@ -0,0 +1,330 @@
+/*
+ * 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 org.jclouds.reflect.Reflection2.method;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+
+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.AtmosHttpApiModule;
+import org.jclouds.atmos.domain.AtmosObject;
+import org.jclouds.atmos.fallbacks.TrueOn404FalseOnPathNotEmpty;
+import org.jclouds.atmos.filters.SignRequest;
+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.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.blobstore.binders.BindBlobToMultipartFormTest;
+import org.jclouds.date.TimeStamp;
+import org.jclouds.http.HttpRequest;
+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.ConfiguresHttpApi;
+import org.jclouds.rest.internal.BaseAsyncClientTest;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+import com.google.common.net.HttpHeaders;
+import com.google.common.reflect.Invokable;
+import com.google.inject.Module;
+
+@Test(groups = "unit", testName = "AtmosClientTest")
+public class AtmosClientTest extends BaseAsyncClientTest<AtmosClient> {
+
+   private BlobToObject blobToObject;
+
+   public void testListDirectories() throws SecurityException, NoSuchMethodException, IOException {
+      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");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": text/xml\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseDirectoryListFromContentAndHeaders.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, null);
+
+      checkFilters(request);
+   }
+
+   public void testListDirectory() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "listDirectory", String.class, ListOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("directory"));
+
+      assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/directory/ HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": text/xml\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseDirectoryListFromContentAndHeaders.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, ThrowContainerNotFoundOn404.class);
+
+      checkFilters(request);
+   }
+
+   public void testListDirectoriesOptions() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "listDirectories", ListOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of(new ListOptions().limit(1).token("asda")));
+
+      assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/ HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": text/xml\nx-emc-limit: 1\nx-emc-token: asda\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseDirectoryListFromContentAndHeaders.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, null);
+
+      checkFilters(request);
+   }
+
+   public void testListDirectoryOptions() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "listDirectory", String.class, ListOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("directory", new ListOptions().limit(1).token("asda")));
+
+      assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/directory/ HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": text/xml\nx-emc-limit: 1\nx-emc-token: asda\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseDirectoryListFromContentAndHeaders.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, ThrowContainerNotFoundOn404.class);
+
+      checkFilters(request);
+   }
+
+   public void testCreateDirectory() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "createDirectory", String.class, PutOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir"));
+
+      assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/ HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
+      assertPayloadEquals(request, "", "application/octet-stream", false);
+
+      assertResponseParserClassEquals(method, request, ParseURIFromListOrLocationHeaderIf20x.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, NullOnKeyAlreadyExists.class);
+
+      checkFilters(request);
+   }
+
+   public void testCreateDirectoryOptions() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "createDirectory", String.class, PutOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", PutOptions.Builder.publicRead()));
+
+      assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/ HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT
+               + ": */*\nx-emc-groupacl: other=READ\nx-emc-useracl: root=FULL_CONTROL\n");
+      assertPayloadEquals(request, "", "application/octet-stream", false);
+
+      assertResponseParserClassEquals(method, request, ParseURIFromListOrLocationHeaderIf20x.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, NullOnKeyAlreadyExists.class);
+
+      checkFilters(request);
+   }
+
+   public void testCreateFile() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "createFile", String.class, AtmosObject.class,
+               PutOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", blobToObject
+               .apply(BindBlobToMultipartFormTest.TEST_BLOB)));
+
+      assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/hello HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\nExpect: 100-continue\n");
+      assertPayloadEquals(request, "hello", "text/plain", false);
+
+      assertResponseParserClassEquals(method, request, ParseNullableURIFromListOrLocationHeaderIf20x.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, null);
+
+      checkFilters(request);
+   }
+
+   public void testCreateFileOptions() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "createFile", String.class, AtmosObject.class,
+               PutOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", blobToObject
+               .apply(BindBlobToMultipartFormTest.TEST_BLOB), PutOptions.Builder.publicRead()));
+
+      assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/hello HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT
+               + ": */*\nExpect: 100-continue\nx-emc-groupacl: other=READ\nx-emc-useracl: root=FULL_CONTROL\n");
+      assertPayloadEquals(request, "hello", "text/plain", false);
+
+      assertResponseParserClassEquals(method, request, ParseNullableURIFromListOrLocationHeaderIf20x.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, null);
+
+      checkFilters(request);
+   }
+
+   public void testUpdateFile() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "updateFile", String.class, AtmosObject.class,
+               PutOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", blobToObject
+               .apply(BindBlobToMultipartFormTest.TEST_BLOB)));
+
+      assertRequestLineEquals(request, "PUT https://accesspoint.atmosonline.com/rest/namespace/dir/hello HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\nExpect: 100-continue\n");
+      assertPayloadEquals(request, "hello", "text/plain", false);
+
+      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, ThrowKeyNotFoundOn404.class);
+
+      checkFilters(request);
+   }
+
+   public void testUpdateFileOptions() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "updateFile", String.class, AtmosObject.class,
+               PutOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir", blobToObject
+               .apply(BindBlobToMultipartFormTest.TEST_BLOB), PutOptions.Builder.publicRead()));
+
+      assertRequestLineEquals(request, "PUT https://accesspoint.atmosonline.com/rest/namespace/dir/hello HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT
+               + ": */*\nExpect: 100-continue\nx-emc-groupacl: other=READ\nx-emc-useracl: root=FULL_CONTROL\n");
+      assertPayloadEquals(request, "hello", "text/plain", false);
+
+      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, ThrowKeyNotFoundOn404.class);
+
+      checkFilters(request);
+   }
+
+   public void testReadFile() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "readFile", String.class, GetOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir/file"));
+
+      assertRequestLineEquals(request, "GET https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseObjectFromHeadersAndHttpContent.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, NullOnNotFoundOr404.class);
+
+      checkFilters(request);
+   }
+
+   public void testGetSystemMetadata() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "getSystemMetadata", String.class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir/file"));
+
+      assertRequestLineEquals(request, "HEAD https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseSystemMetadataFromHeaders.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, NullOnNotFoundOr404.class);
+
+      checkFilters(request);
+   }
+
+   public void testDeletePath() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "deletePath", String.class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir/file"));
+
+      assertRequestLineEquals(request, "DELETE https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, TrueOn404FalseOnPathNotEmpty.class);
+
+      checkFilters(request);
+   }
+
+   public void testIsPublic() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "isPublic", String.class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("dir/file"));
+
+      assertRequestLineEquals(request, "HEAD https://accesspoint.atmosonline.com/rest/namespace/dir/file HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReturnTrueIfGroupACLIsOtherRead.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, FalseOnNotFoundOr404.class);
+
+      checkFilters(request);
+   }
+
+   public void testNewObject() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AtmosClient.class, "newObject");
+      assertEquals(method.getReturnType().getRawType(), AtmosObject.class);
+   }
+
+   @Override
+   protected void checkFilters(HttpRequest request) {
+      assertEquals(request.getFilters().size(), 1);
+      assertEquals(request.getFilters().get(0).getClass(), SignRequest.class);
+   }
+
+   @BeforeClass
+   @Override
+   protected void setupFactory() throws IOException {
+      super.setupFactory();
+      blobToObject = injector.getInstance(BlobToObject.class);
+   }
+
+   @Override
+   protected Module createModule() {
+      return new TestAtmosHttpApiModule();
+   }
+
+      @ConfiguresHttpApi
+   private static final class TestAtmosHttpApiModule extends AtmosHttpApiModule {
+      @Override
+      protected void configure() {
+         super.configure();
+      }
+
+      @Override
+      protected String provideTimeStamp(@TimeStamp Supplier<String> cache) {
+         return "Thu, 05 Jun 2008 16:38:19 GMT";
+      }
+   }
+
+   protected String provider = "atmos";
+
+   @Override
+   public ApiMetadata createApiMetadata() {
+      return new AtmosApiMetadata();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/test/java/org/jclouds/atmos/blobstore/AtmosBlobRequestSignerTest.java
----------------------------------------------------------------------
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 97f8862..39720ab 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;
@@ -45,7 +45,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<AtmosAsyncClient> {
+public class AtmosBlobRequestSignerTest extends BaseAsyncClientTest<AtmosClient> {
 
    public AtmosBlobRequestSignerTest() {
       // this is base64 decoded in the signer;
@@ -126,11 +126,11 @@ public class AtmosBlobRequestSignerTest extends BaseAsyncClientTest<AtmosAsyncCl
 
    @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();

http://git-wip-us.apache.org/repos/asf/jclouds/blob/9b71a9dc/apis/atmos/src/test/java/org/jclouds/atmos/filters/SignRequestTest.java
----------------------------------------------------------------------
diff --git a/apis/atmos/src/test/java/org/jclouds/atmos/filters/SignRequestTest.java b/apis/atmos/src/test/java/org/jclouds/atmos/filters/SignRequestTest.java
index a5418c6..7993bbc 100644
--- a/apis/atmos/src/test/java/org/jclouds/atmos/filters/SignRequestTest.java
+++ b/apis/atmos/src/test/java/org/jclouds/atmos/filters/SignRequestTest.java
@@ -25,12 +25,12 @@ import java.security.NoSuchAlgorithmException;
 import javax.ws.rs.core.MediaType;
 
 import org.jclouds.ContextBuilder;
-import org.jclouds.atmos.config.AtmosRestClientModule;
+import org.jclouds.atmos.config.AtmosHttpApiModule;
 import org.jclouds.atmos.reference.AtmosHeaders;
 import org.jclouds.date.TimeStamp;
 import org.jclouds.http.HttpRequest;
 import org.jclouds.logging.config.NullLoggingModule;
-import org.jclouds.rest.ConfiguresRestClient;
+import org.jclouds.rest.ConfiguresHttpApi;
 import org.jclouds.rest.internal.BaseRestApiTest.MockModule;
 import org.jclouds.util.Strings2;
 import org.testng.annotations.BeforeClass;
@@ -93,15 +93,15 @@ public class SignRequestTest {
             .newBuilder("atmos")
             .credentials(UID, KEY)
             .modules(
-                  ImmutableSet.<Module> of(new MockModule(), new TestAtmosRestClientModule(), new NullLoggingModule()))
+                  ImmutableSet.<Module> 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() {