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

[09/52] [abbrv] JCLOUDS-40 unasync azureblob; plus fold otherwise unused azure-common into it.

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureAsyncBlobStore.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureAsyncBlobStore.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureAsyncBlobStore.java
deleted file mode 100644
index a0bba9f..0000000
--- a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureAsyncBlobStore.java
+++ /dev/null
@@ -1,307 +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.azureblob.blobstore;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.util.concurrent.Futures.transform;
-import static org.jclouds.azure.storage.options.ListOptions.Builder.includeMetadata;
-
-import java.util.List;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Provider;
-import javax.inject.Singleton;
-
-import org.jclouds.Constants;
-import org.jclouds.azure.storage.domain.BoundedSet;
-import org.jclouds.azureblob.AzureBlobAsyncClient;
-import org.jclouds.azureblob.blobstore.functions.AzureBlobToBlob;
-import org.jclouds.azureblob.blobstore.functions.BlobPropertiesToBlobMetadata;
-import org.jclouds.azureblob.blobstore.functions.BlobToAzureBlob;
-import org.jclouds.azureblob.blobstore.functions.ContainerToResourceMetadata;
-import org.jclouds.azureblob.blobstore.functions.ListBlobsResponseToResourceList;
-import org.jclouds.azureblob.blobstore.functions.ListOptionsToListBlobsOptions;
-import org.jclouds.azureblob.blobstore.strategy.MultipartUploadStrategy;
-import org.jclouds.azureblob.domain.AzureBlob;
-import org.jclouds.azureblob.domain.BlobProperties;
-import org.jclouds.azureblob.domain.ContainerProperties;
-import org.jclouds.azureblob.domain.ListBlobBlocksResponse;
-import org.jclouds.azureblob.domain.ListBlobsResponse;
-import org.jclouds.azureblob.domain.PublicAccess;
-import org.jclouds.azureblob.options.ListBlobsOptions;
-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.domain.internal.PageSetImpl;
-import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
-import org.jclouds.blobstore.internal.BaseAsyncBlobStore;
-import org.jclouds.blobstore.options.CreateContainerOptions;
-import org.jclouds.blobstore.options.ListContainerOptions;
-import org.jclouds.blobstore.options.PutOptions;
-import org.jclouds.blobstore.util.BlobUtils;
-import org.jclouds.collect.Memoized;
-import org.jclouds.domain.Location;
-import org.jclouds.http.options.GetOptions;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.collect.Iterables;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import org.jclouds.io.Payload;
-
-/**
- * @deprecated will be removed in jclouds 1.7, as async interfaces are no longer
- *             supported. Please use {@link AzureBlobStore}
- */
-@Deprecated
-@Singleton
-public class AzureAsyncBlobStore extends BaseAsyncBlobStore {
-   private final AzureBlobAsyncClient async;
-   private final ContainerToResourceMetadata container2ResourceMd;
-   private final ListOptionsToListBlobsOptions blobStore2AzureContainerListOptions;
-   private final ListBlobsResponseToResourceList azure2BlobStoreResourceList;
-   private final AzureBlobToBlob azureBlob2Blob;
-   private final BlobToAzureBlob blob2AzureBlob;
-   private final BlobPropertiesToBlobMetadata blob2BlobMd;
-   private final BlobToHttpGetOptions blob2ObjectGetOptions;
-   private final Provider<MultipartUploadStrategy> multipartUploadStrategy;
-
-
-   @Inject
-   AzureAsyncBlobStore(BlobStoreContext context, BlobUtils blobUtils,
-            @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, Supplier<Location> defaultLocation,
-            @Memoized Supplier<Set<? extends Location>> locations, AzureBlobAsyncClient async,
-            ContainerToResourceMetadata container2ResourceMd,
-            ListOptionsToListBlobsOptions blobStore2AzureContainerListOptions,
-            ListBlobsResponseToResourceList azure2BlobStoreResourceList, AzureBlobToBlob azureBlob2Blob,
-            BlobToAzureBlob blob2AzureBlob, BlobPropertiesToBlobMetadata blob2BlobMd,
-            BlobToHttpGetOptions blob2ObjectGetOptions,
-            Provider<MultipartUploadStrategy> multipartUploadStrategy) {
-      super(context, blobUtils, userExecutor, defaultLocation, locations);
-      this.async = checkNotNull(async, "async");
-      this.container2ResourceMd = checkNotNull(container2ResourceMd, "container2ResourceMd");
-      this.blobStore2AzureContainerListOptions = checkNotNull(blobStore2AzureContainerListOptions,
-               "blobStore2AzureContainerListOptions");
-      this.azure2BlobStoreResourceList = checkNotNull(azure2BlobStoreResourceList, "azure2BlobStoreResourceList");
-      this.azureBlob2Blob = checkNotNull(azureBlob2Blob, "azureBlob2Blob");
-      this.blob2AzureBlob = checkNotNull(blob2AzureBlob, "blob2AzureBlob");
-      this.blob2BlobMd = checkNotNull(blob2BlobMd, "blob2BlobMd");
-      this.blob2ObjectGetOptions = checkNotNull(blob2ObjectGetOptions, "blob2ObjectGetOptions");
-      this.multipartUploadStrategy = checkNotNull(multipartUploadStrategy, "multipartUploadStrategy");
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#listContainers} with the
-    * {@link org.jclouds.azure.storage.options.ListOptions#includeMetadata} option.
-    */
-   @Override
-   public ListenableFuture<org.jclouds.blobstore.domain.PageSet<? extends StorageMetadata>> list() {
-      return transform(
-                        async.listContainers(includeMetadata()),
-                        new Function<BoundedSet<ContainerProperties>, org.jclouds.blobstore.domain.PageSet<? extends StorageMetadata>>() {
-                           public org.jclouds.blobstore.domain.PageSet<? extends StorageMetadata> apply(
-                                    BoundedSet<ContainerProperties> from) {
-                              return new PageSetImpl<StorageMetadata>(Iterables.transform(from, container2ResourceMd),
-                                       from.getNextMarker());
-                           }
-                        }, userExecutor);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#containerExists}
-    * 
-    * @param container
-    *           container name
-    */
-   @Override
-   public ListenableFuture<Boolean> containerExists(String container) {
-      return async.containerExists(container);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#createContainer}
-    * 
-    * @param location
-    *           ignored
-    * @param container
-    *           container name
-    */
-   @Override
-   public ListenableFuture<Boolean> createContainerInLocation(Location location, String container) {
-      return async.createContainer(container);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#listBucket}
-    * 
-    * @param container
-    *           container name
-    */
-   @Override
-   public ListenableFuture<PageSet<? extends StorageMetadata>> list(String container, ListContainerOptions options) {
-      ListBlobsOptions azureOptions = blobStore2AzureContainerListOptions.apply(options);
-      ListenableFuture<ListBlobsResponse> returnVal = async.listBlobs(container, azureOptions.includeMetadata());
-      return transform(returnVal, azure2BlobStoreResourceList, userExecutor);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#deleteContainer}
-    * 
-    * @param container
-    *           container name
-    */
-   @Override
-   public ListenableFuture<Void> deleteContainer(final String container) {
-      return async.deleteContainer(container);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#getBlob}
-    * 
-    * @param container
-    *           container name
-    * @param key
-    *           blob key
-    */
-   @Override
-   public ListenableFuture<Blob> getBlob(String container, String key, org.jclouds.blobstore.options.GetOptions options) {
-      GetOptions azureOptions = blob2ObjectGetOptions.apply(options);
-      ListenableFuture<AzureBlob> returnVal = async.getBlob(container, key, azureOptions);
-      return transform(returnVal, azureBlob2Blob, userExecutor);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#putBlob}
-    * 
-    * @param container
-    *           container name
-    * @param blob
-    *           blob
-    */
-   @Override
-   public ListenableFuture<String> putBlob(String container, Blob blob) {
-      return async.putBlob(container, blob2AzureBlob.apply(blob));
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#deleteObject}
-    * 
-    * @param container
-    *           container name
-    * @param key
-    *           blob key
-    */
-   @Override
-   public ListenableFuture<Void> removeBlob(String container, String key) {
-      return async.deleteBlob(container, key);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#blobExists}
-    * 
-    * @param container
-    *           bucket name
-    * @param credential
-    *           object key
-    */
-   @Override
-   public ListenableFuture<Boolean> blobExists(String container, String name) {
-      return async.blobExists(container, name);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#putBlock(String, String, String, Payload)}
-    * @param container
-    * @param name
-    * @param blockId
-    * @param object
-    */
-   public ListenableFuture<Void> putBlock(String container, String name, String blockId, Payload object) {
-      return async.putBlock(container, name, blockId, object);
-   }
-
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#putBlockList(String, String, java.util.List)}
-    * @param container
-    * @param name
-    * @param blockIdList
-    */
-   public ListenableFuture<String> putBlockList(String container, String name, List<String> blockIdList) {
-      return async.putBlockList(container, name, blockIdList);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#getBlockList(String, String)}
-    * @param container
-    * @param name
-    */
-   public ListenableFuture<ListBlobBlocksResponse> getBlockList(String container, String name) {
-      return async.getBlockList(container, name);
-   }
-
-   /**
-    * This implementation invokes {@link AzureBlobAsyncClient#getBlobProperties}
-    * 
-    * @param container
-    *           container name
-    * @param key
-    *           blob key
-    */
-   @Override
-   public ListenableFuture<BlobMetadata> blobMetadata(String container, String key) {
-      return transform(async.getBlobProperties(container, key), new Function<BlobProperties, BlobMetadata>() {
-         public BlobMetadata apply(BlobProperties from) {
-            return blob2BlobMd.apply(from);
-         }
-      }, userExecutor);
-   }
-
-   @Override
-   protected boolean deleteAndVerifyContainerGone(String container) {
-      // Azure deleteContainer supports deleting empty containers so emulate
-      // deleteIfEmpty by listing.
-      if (!Futures.getUnchecked(list(container)).isEmpty()) {
-         return false;
-      }
-      Futures.getUnchecked(async.deleteContainer(container));
-      return true;
-   }
-
-   @Override
-   public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options) {
-      if (options.isMultipart()) {
-         throw new UnsupportedOperationException("Multipart upload not supported in AzureAsyncBlobStore");
-      }
-      return putBlob(container, blob);
-   }
-
-   @Override
-   public ListenableFuture<Boolean> createContainerInLocation(Location location, String container,
-            CreateContainerOptions options) {
-      org.jclouds.azureblob.options.CreateContainerOptions createContainerOptions = new org.jclouds.azureblob.options.CreateContainerOptions();
-      if (options.isPublicRead())
-         createContainerOptions.withPublicAccess(PublicAccess.CONTAINER);
-      return async.createContainer(container, createContainerOptions);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSigner.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSigner.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSigner.java
index 7415981..7a365ed 100644
--- a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSigner.java
+++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSigner.java
@@ -23,7 +23,7 @@ import static org.jclouds.reflect.Reflection2.method;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
-import org.jclouds.azureblob.AzureBlobAsyncClient;
+import org.jclouds.azureblob.AzureBlobClient;
 import org.jclouds.azureblob.blobstore.functions.BlobToAzureBlob;
 import org.jclouds.azureblob.domain.AzureBlob;
 import org.jclouds.blobstore.BlobRequestSigner;
@@ -53,9 +53,9 @@ public class AzureBlobRequestSigner implements BlobRequestSigner {
       this.processor = checkNotNull(processor, "processor");
       this.blobToBlob = checkNotNull(blobToBlob, "blobToBlob");
       this.blob2HttpGetOptions = checkNotNull(blob2HttpGetOptions, "blob2HttpGetOptions");
-      this.getMethod = method(AzureBlobAsyncClient.class, "getBlob", String.class, String.class, GetOptions[].class);
-      this.deleteMethod = method(AzureBlobAsyncClient.class, "deleteBlob", String.class, String.class);
-      this.createMethod = method(AzureBlobAsyncClient.class, "putBlob", String.class, AzureBlob.class);
+      this.getMethod = method(AzureBlobClient.class, "getBlob", String.class, String.class, GetOptions[].class);
+      this.deleteMethod = method(AzureBlobClient.class, "deleteBlob", String.class, String.class);
+      this.createMethod = method(AzureBlobClient.class, "putBlob", String.class, AzureBlob.class);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/config/AzureBlobStoreContextModule.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/config/AzureBlobStoreContextModule.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/config/AzureBlobStoreContextModule.java
index dce2e58..aef156d 100644
--- a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/config/AzureBlobStoreContextModule.java
+++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/config/AzureBlobStoreContextModule.java
@@ -21,7 +21,6 @@ import java.util.concurrent.TimeUnit;
 import javax.inject.Singleton;
 
 import org.jclouds.azureblob.AzureBlobClient;
-import org.jclouds.azureblob.blobstore.AzureAsyncBlobStore;
 import org.jclouds.azureblob.blobstore.AzureBlobRequestSigner;
 import org.jclouds.azureblob.blobstore.AzureBlobStore;
 import org.jclouds.azureblob.domain.PublicAccess;
@@ -29,6 +28,7 @@ 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;
@@ -37,15 +37,12 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Scopes;
 
-/**
- * Configures the {@link AzureBlobStoreContext}; requires {@link AzureAsyncBlobStore} bound.
- */
 public class AzureBlobStoreContextModule extends AbstractModule {
 
    @Override
    protected void configure() {
       bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
-      bind(AsyncBlobStore.class).to(AzureAsyncBlobStore.class).in(Scopes.SINGLETON);
+      bind(AsyncBlobStore.class).to(SubmissionAsyncBlobStore.class).in(Scopes.SINGLETON);
       bind(BlobStore.class).to(AzureBlobStore.class).in(Scopes.SINGLETON);
       bind(BlobRequestSigner.class).to(AzureBlobRequestSigner.class);
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/main/java/org/jclouds/azureblob/config/AzureBlobHttpApiModule.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/config/AzureBlobHttpApiModule.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/config/AzureBlobHttpApiModule.java
new file mode 100644
index 0000000..52a4195
--- /dev/null
+++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/config/AzureBlobHttpApiModule.java
@@ -0,0 +1,88 @@
+/*
+ * 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.azureblob.config;
+
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+import static org.jclouds.json.config.GsonModule.DateAdapter;
+import static org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Named;
+
+import org.jclouds.azure.storage.handlers.AzureStorageClientErrorRetryHandler;
+import org.jclouds.azureblob.AzureBlobClient;
+import org.jclouds.azureblob.handlers.ParseAzureBlobErrorFromXmlContent;
+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 Azure Blob Service connection, including logging and http transport.
+ */
+@ConfiguresHttpApi
+public class AzureBlobHttpApiModule extends HttpApiModule<AzureBlobClient> {
+
+   @Override
+   protected void configure() {
+      install(new AzureBlobModule());
+      bind(DateAdapter.class).to(Iso8601DateAdapter.class);
+      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
+   protected Supplier<String> provideTimeStampCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
+         final DateService dateService) {
+      return Suppliers.memoizeWithExpiration(new Supplier<String>() {
+         public String get() {
+            return dateService.rfc822DateFormat();
+         }
+      }, seconds, TimeUnit.SECONDS);
+   }
+
+   @Override
+   protected void bindRetryHandlers() {
+      bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(AzureStorageClientErrorRetryHandler.class);
+   }
+
+   @Override
+   protected void bindErrorHandlers() {
+      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseAzureBlobErrorFromXmlContent.class);
+      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseAzureBlobErrorFromXmlContent.class);
+      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseAzureBlobErrorFromXmlContent.class);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/main/java/org/jclouds/azureblob/config/AzureBlobRestClientModule.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/config/AzureBlobRestClientModule.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/config/AzureBlobRestClientModule.java
deleted file mode 100644
index 4b62ebf..0000000
--- a/providers/azureblob/src/main/java/org/jclouds/azureblob/config/AzureBlobRestClientModule.java
+++ /dev/null
@@ -1,48 +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.azureblob.config;
-
-import org.jclouds.azure.storage.config.AzureStorageRestClientModule;
-import org.jclouds.azureblob.AzureBlobAsyncClient;
-import org.jclouds.azureblob.AzureBlobClient;
-import org.jclouds.azureblob.handlers.ParseAzureBlobErrorFromXmlContent;
-import org.jclouds.http.HttpErrorHandler;
-import org.jclouds.http.annotation.ClientError;
-import org.jclouds.http.annotation.Redirection;
-import org.jclouds.http.annotation.ServerError;
-import org.jclouds.rest.ConfiguresRestClient;
-
-/**
- * Configures the Azure Blob Service connection, including logging and http transport.
- */
-@ConfiguresRestClient
-public class AzureBlobRestClientModule extends AzureStorageRestClientModule<AzureBlobClient, AzureBlobAsyncClient> {
-
-   @Override
-   protected void configure() {
-      install(new AzureBlobModule());
-      super.configure();
-   }
-
-   @Override
-   protected void bindErrorHandlers() {
-      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseAzureBlobErrorFromXmlContent.class);
-      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(ParseAzureBlobErrorFromXmlContent.class);
-      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(ParseAzureBlobErrorFromXmlContent.class);
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java b/providers/azureblob/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java
new file mode 100644
index 0000000..5bea836
--- /dev/null
+++ b/providers/azureblob/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azure.storage.filters;
+
+import static org.jclouds.reflect.Reflection2.typeToken;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.URI;
+
+import javax.ws.rs.HttpMethod;
+
+import org.jclouds.ContextBuilder;
+import org.jclouds.azure.storage.config.AzureStorageRestClientModule;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.IntegrationTestAsyncClient;
+import org.jclouds.http.IntegrationTestClient;
+import org.jclouds.logging.config.NullLoggingModule;
+import org.jclouds.rest.AnonymousRestApiMetadata;
+import org.jclouds.rest.internal.BaseRestApiTest.MockModule;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.net.HttpHeaders;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
+@Test(groups = "unit")
+public class SharedKeyLiteAuthenticationTest {
+
+   private static final String ACCOUNT = "foo";
+   private Injector injector;
+   private SharedKeyLiteAuthentication filter;
+
+   @DataProvider(parallel = true)
+   public Object[][] dataProvider() {
+      return new Object[][] {
+            { HttpRequest.builder().method(HttpMethod.PUT).endpoint("http://" + ACCOUNT
+                  + ".blob.core.windows.net/movies/MOV1.avi?comp=block&blockid=BlockId1&timeout=60").build() },
+            { HttpRequest.builder().method(HttpMethod.PUT).endpoint("http://" + ACCOUNT
+                  + ".blob.core.windows.net/movies/MOV1.avi?comp=blocklist&timeout=120").build() },
+            { HttpRequest.builder().method(HttpMethod.GET).endpoint("http://" + ACCOUNT + ".blob.core.windows.net/movies/MOV1.avi").build() } };
+   }
+
+   /**
+    * NOTE this test is dependent on how frequently the timestamp updates. At
+    * the time of writing, this was once per second. If this timestamp update
+    * interval is increased, it could make this test appear to hang for a long
+    * time.
+    */
+   @Test(threadPoolSize = 3, dataProvider = "dataProvider", timeOut = 3000)
+   void testIdempotent(HttpRequest request) {
+      request = filter.filter(request);
+      String signature = request.getFirstHeaderOrNull(HttpHeaders.AUTHORIZATION);
+      String date = request.getFirstHeaderOrNull(HttpHeaders.DATE);
+      int iterations = 1;
+      while (request.getFirstHeaderOrNull(HttpHeaders.DATE).equals(date)) {
+         date = request.getFirstHeaderOrNull(HttpHeaders.DATE);
+         iterations++;
+         assertEquals(signature, request.getFirstHeaderOrNull(HttpHeaders.AUTHORIZATION));
+         request = filter.filter(request);
+      }
+      System.out.printf("%s: %d iterations before the timestamp updated %n", Thread.currentThread().getName(),
+            iterations);
+   }
+
+   @Test
+   void testAclQueryStringRoot() {
+      URI host = URI.create("http://" + ACCOUNT + ".blob.core.windows.net/?comp=list");
+      HttpRequest request = HttpRequest.builder().method(HttpMethod.GET).endpoint(host).build();
+      StringBuilder builder = new StringBuilder();
+      filter.appendUriPath(request, builder);
+      assertEquals(builder.toString(), "/?comp=list");
+   }
+
+   @Test
+   void testAclQueryStringResTypeNotSignificant() {
+      URI host = URI.create("http://" + ACCOUNT + ".blob.core.windows.net/mycontainer?restype=container");
+      HttpRequest request = HttpRequest.builder().method(HttpMethod.GET).endpoint(host).build();
+      StringBuilder builder = new StringBuilder();
+      filter.appendUriPath(request, builder);
+      assertEquals(builder.toString(), "/mycontainer");
+   }
+
+   @Test
+   void testAclQueryStringComp() {
+      URI host = URI.create("http://" + ACCOUNT + ".blob.core.windows.net/mycontainer?comp=list");
+      HttpRequest request = HttpRequest.builder().method(HttpMethod.GET).endpoint(host).build();
+      StringBuilder builder = new StringBuilder();
+      filter.appendUriPath(request, builder);
+      assertEquals(builder.toString(), "/mycontainer?comp=list");
+   }
+
+   @Test
+   void testAclQueryStringRelativeWithExtraJunk() {
+      URI host = URI.create("http://" + ACCOUNT
+            + ".blob.core.windows.net/mycontainer?comp=list&marker=marker&maxresults=1&prefix=prefix");
+      HttpRequest request = HttpRequest.builder().method(HttpMethod.GET).endpoint(host).build();
+      StringBuilder builder = new StringBuilder();
+      filter.appendUriPath(request, builder);
+      assertEquals(builder.toString(), "/mycontainer?comp=list");
+   }
+
+   /**
+    * before class, as we need to ensure that the filter is threadsafe.
+    * 
+    * @throws IOException
+    * 
+    */
+   @BeforeClass
+   protected void createFilter() throws IOException {
+      injector = ContextBuilder
+            .newBuilder(
+                  AnonymousRestApiMetadata
+                        .forClientMappedToAsyncClient(IntegrationTestClient.class, IntegrationTestAsyncClient.class)
+                        .toBuilder().build())
+            .endpoint("https://${jclouds.identity}.blob.core.windows.net")
+            .credentials(ACCOUNT, "credential")
+            .modules(
+                  ImmutableSet.<Module> of(new MockModule(), new NullLoggingModule(),
+                        new AzureStorageRestClientModule<IntegrationTestClient, IntegrationTestAsyncClient>(
+                              typeToken(IntegrationTestClient.class), typeToken(IntegrationTestAsyncClient.class))))
+            .buildInjector();
+      filter = injector.getInstance(SharedKeyLiteAuthentication.class);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java b/providers/azureblob/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java
new file mode 100644
index 0000000..5cfbffe
--- /dev/null
+++ b/providers/azureblob/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azure.storage.handlers;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reportMatcher;
+import static org.easymock.EasyMock.verify;
+
+import java.net.URI;
+
+import org.easymock.IArgumentMatcher;
+import org.jclouds.azure.storage.AzureStorageResponseException;
+import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.functions.config.SaxParserModule;
+import org.testng.annotations.Test;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+
+@Test(groups = { "unit" })
+public class ParseAzureErrorFromXmlContentTest {
+
+   @Test
+   public void test411WithTextHtmlIllegalArgumentException() {
+      assertCodeMakes("PUT",
+            URI.create("https://jclouds.blob.core.windows.net/adriancole-azureblob-413790770?restype=container"), 411,
+            "Length Required", "text/html; charset=us-ascii", "<HTML><HEAD><TITLE>Length Required</TITLE>\r\n",
+            IllegalArgumentException.class);
+   }
+
+   @Test
+   public void test304WithNoContentIllegalArgumentException() {
+      assertCodeMakes("GET", URI.create("https://jclouds.blob.core.windows.net/adriancole-blobstore0/apples"), 411,
+            "HTTP/1.1 304 The condition specified using HTTP conditional header(s) is not met.", "application/unknown",
+            "", IllegalArgumentException.class);
+   }
+
+   
+   @Test
+   public void test412WithTextHtmlHttpResponseException() {
+      assertCodeMakes(
+            "GET",
+            URI.create("https://jclouds.blob.core.windows.net/adriancole-blobstore2?restype=container&comp=list&prefix=apps/apps/apps/&include=metadata"),
+            412,
+            "HTTP/1.1 412 The condition specified using HTTP conditional header(s) is not met.",
+            "application/xml",
+            "<?xml version=\"1.0\" encoding=\"utf-8\"?><Error><Code>ConditionNotMet</Code><Message>The condition specified using HTTP conditional header(s) is not met.\nRequestId:921efcad-84bc-4e0a-863d-24810d1096e1\nTime:2010-11-04T15:03:07.8694513Z</Message></Error>",
+            AzureStorageResponseException.class);
+   }
+
+   private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
+         String content, Class<? extends Exception> expected) {
+
+      ParseAzureStorageErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() {
+
+         @Override
+         protected void configure() {
+            bind(SharedKeyLiteAuthentication.class).toInstance(createMock(SharedKeyLiteAuthentication.class));
+         }
+
+      }).getInstance(ParseAzureStorageErrorFromXmlContent.class);
+
+      HttpCommand command = createMock(HttpCommand.class);
+      HttpRequest request = HttpRequest.builder().method(method).endpoint(uri).build();
+      HttpResponse response = HttpResponse.builder().statusCode(statusCode).message(message).payload(content).build();
+      response.getPayload().getContentMetadata().setContentType(contentType);
+
+      expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
+      command.setException(classEq(expected));
+
+      replay(command);
+
+      function.handleError(command, response);
+
+      verify(command);
+   }
+
+   public static Exception classEq(final Class<? extends Exception> in) {
+      reportMatcher(new IArgumentMatcher() {
+
+         @Override
+         public void appendTo(StringBuffer buffer) {
+            buffer.append("classEq(");
+            buffer.append(in);
+            buffer.append(")");
+         }
+
+         @Override
+         public boolean matches(Object arg) {
+            return arg.getClass() == in;
+         }
+
+      });
+      return null;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azure/storage/options/CreateOptionsTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azure/storage/options/CreateOptionsTest.java b/providers/azureblob/src/test/java/org/jclouds/azure/storage/options/CreateOptionsTest.java
new file mode 100644
index 0000000..b582783
--- /dev/null
+++ b/providers/azureblob/src/test/java/org/jclouds/azure/storage/options/CreateOptionsTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azure.storage.options;
+
+import static org.testng.Assert.assertEquals;
+
+import org.jclouds.azure.storage.reference.AzureStorageHeaders;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMultimap;
+
+/**
+ * Tests behavior of {@code CreateOptions}
+ */
+@Test(groups = "unit")
+public class CreateOptionsTest {
+
+   public void testMetadata() {
+      CreateOptions options = new CreateOptions().withMetadata(ImmutableMultimap.of(
+               "test", "foo"));
+      assertEquals(ImmutableList.of("foo"), options.buildRequestHeaders().get(
+               AzureStorageHeaders.USER_METADATA_PREFIX + "test"));
+   }
+
+   public void testMetadataAlreadyPrefixed() {
+      CreateOptions options = new CreateOptions().withMetadata(ImmutableMultimap.of(
+               AzureStorageHeaders.USER_METADATA_PREFIX + "test", "foo"));
+      assertEquals(ImmutableList.of("foo"), options.buildRequestHeaders().get(
+               AzureStorageHeaders.USER_METADATA_PREFIX + "test"));
+   }
+
+   public void testMetadataStatic() {
+      CreateOptions options = CreateOptions.Builder.withMetadata(ImmutableMultimap.of(
+               "test", "foo"));
+      assertEquals(ImmutableList.of("foo"), options.buildRequestHeaders().get(
+               AzureStorageHeaders.USER_METADATA_PREFIX + "test"));
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azure/storage/options/ListOptionsTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azure/storage/options/ListOptionsTest.java b/providers/azureblob/src/test/java/org/jclouds/azure/storage/options/ListOptionsTest.java
new file mode 100644
index 0000000..67fc768
--- /dev/null
+++ b/providers/azureblob/src/test/java/org/jclouds/azure/storage/options/ListOptionsTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azure.storage.options;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Tests behavior of {@code ListOptions}
+ */
+@Test(groups = "unit")
+public class ListOptionsTest {
+   public void testIncludeMetadata() {
+      ListOptions options = new ListOptions().includeMetadata();
+      assertEquals(ImmutableList.of("metadata"), options.buildQueryParameters().get("include"));
+   }
+
+   public void testIncludeMetadataStatic() {
+      ListOptions options = ListOptions.Builder.includeMetadata();
+      assertEquals(ImmutableList.of("metadata"), options.buildQueryParameters().get("include"));
+   }
+
+   public void testPrefix() {
+      ListOptions options = new ListOptions().prefix("a");
+      assertEquals(ImmutableList.of("a"), options.buildQueryParameters().get("prefix"));
+   }
+
+   public void testMarker() {
+      ListOptions options = new ListOptions().marker("a");
+      assertEquals(ImmutableList.of("a"), options.buildQueryParameters().get("marker"));
+   }
+
+   public void testMaxResults() {
+      int limit = 1;
+      ListOptions options = new ListOptions().maxResults(limit);
+      assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("maxresults"));
+   }
+
+   public void testPrefixStatic() {
+      ListOptions options = ListOptions.Builder.prefix("a");
+      assertEquals(ImmutableList.of("a"), options.buildQueryParameters().get("prefix"));
+   }
+
+   public void testMarkerStatic() {
+      ListOptions options = ListOptions.Builder.marker("a");
+      assertEquals(ImmutableList.of("a"), options.buildQueryParameters().get("marker"));
+   }
+
+   public void testMaxResultsStatic() {
+      int limit = 1;
+      ListOptions options = ListOptions.Builder.maxResults(limit);
+      assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("maxresults"));
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azure/storage/xml/ErrorHandlerTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azure/storage/xml/ErrorHandlerTest.java b/providers/azureblob/src/test/java/org/jclouds/azure/storage/xml/ErrorHandlerTest.java
new file mode 100644
index 0000000..1698cd6
--- /dev/null
+++ b/providers/azureblob/src/test/java/org/jclouds/azure/storage/xml/ErrorHandlerTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azure.storage.xml;
+
+import static org.testng.Assert.assertEquals;
+
+import java.io.InputStream;
+
+import org.jclouds.azure.storage.domain.AzureStorageError;
+import org.jclouds.http.functions.BaseHandlerTest;
+import org.jclouds.http.functions.ParseSax;
+import org.testng.annotations.Test;
+
+/**
+ * Tests behavior of {@code ErrorHandler}
+ */
+// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
+@Test(groups = "unit", testName = "ErrorHandlerTest")
+public class ErrorHandlerTest extends BaseHandlerTest {
+
+   ParseSax<AzureStorageError> createParser() {
+      ParseSax<AzureStorageError> parser = factory.create(injector
+               .getInstance(ErrorHandler.class));
+      return parser;
+   }
+
+   public void testApplyInputStream() {
+      InputStream is = getClass().getResourceAsStream("/test_error.xml");
+      ParseSax<AzureStorageError> parser = createParser();
+      AzureStorageError result = parser.parse(is);
+      assertEquals(result.getCode(), "AuthenticationFailed");
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobAsyncClientTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobAsyncClientTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobAsyncClientTest.java
deleted file mode 100644
index 17a9cb8..0000000
--- a/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobAsyncClientTest.java
+++ /dev/null
@@ -1,294 +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.azureblob;
-
-import static org.jclouds.azure.storage.options.ListOptions.Builder.maxResults;
-import static org.jclouds.azureblob.options.CreateContainerOptions.Builder.withPublicAccess;
-import static org.jclouds.reflect.Reflection2.method;
-import static org.testng.Assert.assertEquals;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.jclouds.Fallbacks.TrueOnNotFoundOr404;
-import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
-import org.jclouds.azure.storage.options.ListOptions;
-import org.jclouds.azureblob.AzureBlobFallbacks.FalseIfContainerAlreadyExists;
-import org.jclouds.azureblob.domain.PublicAccess;
-import org.jclouds.azureblob.functions.ParseBlobFromHeadersAndHttpContent;
-import org.jclouds.azureblob.functions.ParseContainerPropertiesFromHeaders;
-import org.jclouds.azureblob.functions.ParsePublicAccessHeader;
-import org.jclouds.azureblob.options.CreateContainerOptions;
-import org.jclouds.azureblob.options.ListBlobsOptions;
-import org.jclouds.azureblob.xml.AccountNameEnumerationResultsHandler;
-import org.jclouds.azureblob.xml.ContainerNameEnumerationResultsHandler;
-import org.jclouds.blobstore.BlobStoreFallbacks.NullOnContainerNotFound;
-import org.jclouds.blobstore.BlobStoreFallbacks.NullOnKeyNotFound;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.functions.ParseSax;
-import org.jclouds.http.functions.ReleasePayloadAndReturn;
-import org.jclouds.http.functions.ReturnTrueIf2xx;
-import org.jclouds.http.options.GetOptions;
-import org.jclouds.rest.internal.BaseAsyncClientTest;
-import org.jclouds.rest.internal.GeneratedHttpRequest;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.reflect.Invokable;
-/**
- * Tests behavior of {@code AzureBlobAsyncClient}
- */
-// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
-@Test(groups = "unit", testName = "AzureBlobAsyncClientTest")
-public class AzureBlobAsyncClientTest extends BaseAsyncClientTest<AzureBlobAsyncClient> {
-
-   public void testListContainers() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "listContainers", ListOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of());
-
-      assertRequestLineEquals(request, "GET https://identity.blob.core.windows.net/?comp=list HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, AccountNameEnumerationResultsHandler.class);
-      assertFallbackClassEquals(method, null);
-
-   }
-
-   public void testListContainersOptions() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "listContainers", ListOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of(maxResults(1).marker("marker").prefix("prefix")));
-
-      assertRequestLineEquals(request,
-               "GET https://identity.blob.core.windows.net/?comp=list&maxresults=1&marker=marker&prefix=prefix HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, AccountNameEnumerationResultsHandler.class);
-      assertFallbackClassEquals(method, null);
-   }
-
-   public void testCreateContainer() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "createContainer", String.class,
-               CreateContainerOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
-
-      assertRequestLineEquals(request,
-               "PUT https://identity.blob.core.windows.net/container?restype=container HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseIfContainerAlreadyExists.class);
-   }
-
-   public void testDeleteContainer() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "deleteContainer", String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
-
-      assertRequestLineEquals(request,
-               "DELETE https://identity.blob.core.windows.net/container?restype=container HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, VoidOnNotFoundOr404.class);
-   }
-
-   public void testCreateContainerOptions() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "createContainer", String.class,
-               CreateContainerOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container", withPublicAccess(PublicAccess.BLOB)
-               .withMetadata(ImmutableMultimap.of("foo", "bar"))));
-
-      assertRequestLineEquals(request,
-               "PUT https://identity.blob.core.windows.net/container?restype=container HTTP/1.1");
-      assertNonPayloadHeadersEqual(request,
-               "x-ms-blob-public-access: blob\n" +
-               "x-ms-meta-foo: bar\n" +
-               "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseIfContainerAlreadyExists.class);
-   }
-
-   public void testCreateRootContainer() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "createRootContainer", CreateContainerOptions[].class);
-
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of());
-
-      assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseIfContainerAlreadyExists.class);
-   }
-
-   public void testDeleteRootContainer() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "deleteRootContainer");
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of());
-
-      assertRequestLineEquals(request, "DELETE https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, TrueOnNotFoundOr404.class);
-   }
-
-   public void testCreateRootContainerOptions() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "createRootContainer", CreateContainerOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of(withPublicAccess(PublicAccess.BLOB).withMetadata(
-               ImmutableMultimap.of("foo", "bar"))));
-
-      assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
-      assertNonPayloadHeadersEqual(request,
-               "x-ms-blob-public-access: blob\n" +
-               "x-ms-meta-foo: bar\n" +
-               "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, FalseIfContainerAlreadyExists.class);
-   }
-
-   public void testListBlobs() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "listBlobs", String.class, ListBlobsOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
-
-      assertRequestLineEquals(request,
-               "GET https://identity.blob.core.windows.net/container?restype=container&comp=list HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, ContainerNameEnumerationResultsHandler.class);
-      assertFallbackClassEquals(method, null);
-   }
-
-   public void testListRootBlobs() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "listBlobs", ListBlobsOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of());
-
-      assertRequestLineEquals(request,
-               "GET https://identity.blob.core.windows.net/$root?restype=container&comp=list HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseSax.class);
-      assertSaxResponseParserClassEquals(method, ContainerNameEnumerationResultsHandler.class);
-      assertFallbackClassEquals(method, null);
-   }
-
-   public void testContainerProperties() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "getContainerProperties", String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
-
-      assertRequestLineEquals(request,
-               "HEAD https://identity.blob.core.windows.net/container?restype=container HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseContainerPropertiesFromHeaders.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, NullOnContainerNotFound.class);
-   }
-
-   public void testGetPublicAccessForContainer() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "getPublicAccessForContainer", String.class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
-
-      assertRequestLineEquals(request,
-               "HEAD https://identity.blob.core.windows.net/container?restype=container&comp=acl HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParsePublicAccessHeader.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, NullOnContainerNotFound.class);
-   }
-
-   public void testSetResourceMetadata() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "setResourceMetadata", String.class, Map.class);
-      GeneratedHttpRequest request = processor.createRequest(method,
-            ImmutableList.<Object> of("container", ImmutableMap.of("key", "value")));
-
-      assertRequestLineEquals(request,
-               "PUT https://identity.blob.core.windows.net/container?restype=container&comp=metadata HTTP/1.1");
-      assertNonPayloadHeadersEqual(request,
-               "x-ms-meta-key: value\n" +
-               "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-   }
-
-   public void testGetBlob() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "getBlob", String.class, String.class, GetOptions[].class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container", "blob"));
-
-      assertRequestLineEquals(request, "GET https://identity.blob.core.windows.net/container/blob HTTP/1.1");
-      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ParseBlobFromHeadersAndHttpContent.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, NullOnKeyNotFound.class);
-   }
-
-   public void testSetBlobMetadata() throws SecurityException, NoSuchMethodException, IOException {
-      Invokable<?, ?> method = method(AzureBlobAsyncClient.class, "setBlobMetadata", String.class, String.class, Map.class);
-      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container", "blob", ImmutableMap.of("key", "value")));
-
-      assertRequestLineEquals(request,
-               "PUT https://identity.blob.core.windows.net/container/blob?comp=metadata HTTP/1.1");
-      assertNonPayloadHeadersEqual(request,
-               "x-ms-meta-key: value\n" +
-               "x-ms-version: 2012-02-12\n");
-      assertPayloadEquals(request, null, null, false);
-
-      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
-      assertSaxResponseParserClassEquals(method, null);
-      assertFallbackClassEquals(method, null);
-   }
-
-   @Override
-   protected void checkFilters(HttpRequest request) {
-      assertEquals(request.getFilters().size(), 1);
-      assertEquals(request.getFilters().get(0).getClass(), SharedKeyLiteAuthentication.class);
-   }
-
-   @Override
-   public AzureBlobProviderMetadata createProviderMetadata() {
-      return new AzureBlobProviderMetadata();
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientLiveTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientLiveTest.java
index 5966e7b..5ad73d1 100644
--- a/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientLiveTest.java
+++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientLiveTest.java
@@ -30,7 +30,6 @@ import java.security.SecureRandom;
 import java.util.Arrays;
 import java.util.Set;
 
-import com.google.common.io.BaseEncoding;
 import org.jclouds.azure.storage.AzureStorageResponseException;
 import org.jclouds.azure.storage.domain.BoundedSet;
 import org.jclouds.azure.storage.options.ListOptions;
@@ -55,10 +54,8 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Iterables;
 import com.google.common.hash.Hashing;
+import com.google.common.io.BaseEncoding;
 
-/**
- * Tests behavior of {@code AzureBlobClient}
- */
 @Test(groups = "live", singleThreaded = true)
 public class AzureBlobClientLiveTest extends BaseBlobStoreIntegrationTest {
    public AzureBlobClientLiveTest() {
@@ -66,7 +63,7 @@ public class AzureBlobClientLiveTest extends BaseBlobStoreIntegrationTest {
    }
 
    public AzureBlobClient getApi() {
-      return view.unwrap(AzureBlobApiMetadata.CONTEXT_TOKEN).getApi();
+      return view.unwrapApi(AzureBlobClient.class);
    }
 
    @Test
@@ -100,8 +97,8 @@ public class AzureBlobClientLiveTest extends BaseBlobStoreIntegrationTest {
       long containerCount = response.size();
       assertTrue(containerCount >= 1);
       ListBlobsResponse list = getApi().listBlobs(privateContainer);
-      assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/%s", view.unwrap(
-               AzureBlobApiMetadata.CONTEXT_TOKEN).getIdentity(), privateContainer)));
+      assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/%s",
+            view.unwrap().getIdentity(), privateContainer)));
       // TODO .. check to see the container actually exists
    }
 
@@ -156,8 +153,8 @@ public class AzureBlobClientLiveTest extends BaseBlobStoreIntegrationTest {
          }
       }
       ListBlobsResponse list = getApi().listBlobs();
-      assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/$root", view.unwrap(
-               AzureBlobApiMetadata.CONTEXT_TOKEN).getIdentity())));
+      assertEquals(list.getUrl(), URI.create(String.format("https://%s.blob.core.windows.net/$root",
+            view.unwrap().getIdentity())));
    }
 
    @Test

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientTest.java
new file mode 100644
index 0000000..34f0c5c
--- /dev/null
+++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/AzureBlobClientTest.java
@@ -0,0 +1,291 @@
+/*
+ * 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.azureblob;
+
+import static org.jclouds.azure.storage.options.ListOptions.Builder.maxResults;
+import static org.jclouds.azureblob.options.CreateContainerOptions.Builder.withPublicAccess;
+import static org.jclouds.reflect.Reflection2.method;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.jclouds.Fallbacks.TrueOnNotFoundOr404;
+import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
+import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
+import org.jclouds.azure.storage.options.ListOptions;
+import org.jclouds.azureblob.AzureBlobFallbacks.FalseIfContainerAlreadyExists;
+import org.jclouds.azureblob.domain.PublicAccess;
+import org.jclouds.azureblob.functions.ParseBlobFromHeadersAndHttpContent;
+import org.jclouds.azureblob.functions.ParseContainerPropertiesFromHeaders;
+import org.jclouds.azureblob.functions.ParsePublicAccessHeader;
+import org.jclouds.azureblob.options.CreateContainerOptions;
+import org.jclouds.azureblob.options.ListBlobsOptions;
+import org.jclouds.azureblob.xml.AccountNameEnumerationResultsHandler;
+import org.jclouds.azureblob.xml.ContainerNameEnumerationResultsHandler;
+import org.jclouds.blobstore.BlobStoreFallbacks.NullOnContainerNotFound;
+import org.jclouds.blobstore.BlobStoreFallbacks.NullOnKeyNotFound;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.functions.ParseSax;
+import org.jclouds.http.functions.ReleasePayloadAndReturn;
+import org.jclouds.http.functions.ReturnTrueIf2xx;
+import org.jclouds.http.options.GetOptions;
+import org.jclouds.rest.internal.BaseAsyncClientTest;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.reflect.Invokable;
+
+@Test(groups = "unit", testName = "AzureBlobClientTest")
+public class AzureBlobClientTest extends BaseAsyncClientTest<AzureBlobClient> {
+
+   public void testListContainers() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "listContainers", ListOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of());
+
+      assertRequestLineEquals(request, "GET https://identity.blob.core.windows.net/?comp=list HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseSax.class);
+      assertSaxResponseParserClassEquals(method, AccountNameEnumerationResultsHandler.class);
+      assertFallbackClassEquals(method, null);
+
+   }
+
+   public void testListContainersOptions() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "listContainers", ListOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of(maxResults(1).marker("marker").prefix("prefix")));
+
+      assertRequestLineEquals(request,
+               "GET https://identity.blob.core.windows.net/?comp=list&maxresults=1&marker=marker&prefix=prefix HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseSax.class);
+      assertSaxResponseParserClassEquals(method, AccountNameEnumerationResultsHandler.class);
+      assertFallbackClassEquals(method, null);
+   }
+
+   public void testCreateContainer() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "createContainer", String.class,
+               CreateContainerOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
+
+      assertRequestLineEquals(request,
+               "PUT https://identity.blob.core.windows.net/container?restype=container HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, FalseIfContainerAlreadyExists.class);
+   }
+
+   public void testDeleteContainer() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "deleteContainer", String.class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
+
+      assertRequestLineEquals(request,
+               "DELETE https://identity.blob.core.windows.net/container?restype=container HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, VoidOnNotFoundOr404.class);
+   }
+
+   public void testCreateContainerOptions() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "createContainer", String.class,
+               CreateContainerOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container", withPublicAccess(PublicAccess.BLOB)
+               .withMetadata(ImmutableMultimap.of("foo", "bar"))));
+
+      assertRequestLineEquals(request,
+               "PUT https://identity.blob.core.windows.net/container?restype=container HTTP/1.1");
+      assertNonPayloadHeadersEqual(request,
+               "x-ms-blob-public-access: blob\n" +
+               "x-ms-meta-foo: bar\n" +
+               "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, FalseIfContainerAlreadyExists.class);
+   }
+
+   public void testCreateRootContainer() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "createRootContainer", CreateContainerOptions[].class);
+
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of());
+
+      assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, FalseIfContainerAlreadyExists.class);
+   }
+
+   public void testDeleteRootContainer() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "deleteRootContainer");
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of());
+
+      assertRequestLineEquals(request, "DELETE https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, TrueOnNotFoundOr404.class);
+   }
+
+   public void testCreateRootContainerOptions() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "createRootContainer", CreateContainerOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of(withPublicAccess(PublicAccess.BLOB).withMetadata(
+               ImmutableMultimap.of("foo", "bar"))));
+
+      assertRequestLineEquals(request, "PUT https://identity.blob.core.windows.net/$root?restype=container HTTP/1.1");
+      assertNonPayloadHeadersEqual(request,
+               "x-ms-blob-public-access: blob\n" +
+               "x-ms-meta-foo: bar\n" +
+               "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, FalseIfContainerAlreadyExists.class);
+   }
+
+   public void testListBlobs() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "listBlobs", String.class, ListBlobsOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
+
+      assertRequestLineEquals(request,
+               "GET https://identity.blob.core.windows.net/container?restype=container&comp=list HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseSax.class);
+      assertSaxResponseParserClassEquals(method, ContainerNameEnumerationResultsHandler.class);
+      assertFallbackClassEquals(method, null);
+   }
+
+   public void testListRootBlobs() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "listBlobs", ListBlobsOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.of());
+
+      assertRequestLineEquals(request,
+               "GET https://identity.blob.core.windows.net/$root?restype=container&comp=list HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseSax.class);
+      assertSaxResponseParserClassEquals(method, ContainerNameEnumerationResultsHandler.class);
+      assertFallbackClassEquals(method, null);
+   }
+
+   public void testContainerProperties() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "getContainerProperties", String.class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
+
+      assertRequestLineEquals(request,
+               "HEAD https://identity.blob.core.windows.net/container?restype=container HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseContainerPropertiesFromHeaders.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, NullOnContainerNotFound.class);
+   }
+
+   public void testGetPublicAccessForContainer() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "getPublicAccessForContainer", String.class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container"));
+
+      assertRequestLineEquals(request,
+               "HEAD https://identity.blob.core.windows.net/container?restype=container&comp=acl HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParsePublicAccessHeader.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, NullOnContainerNotFound.class);
+   }
+
+   public void testSetResourceMetadata() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "setResourceMetadata", String.class, Map.class);
+      GeneratedHttpRequest request = processor.createRequest(method,
+            ImmutableList.<Object> of("container", ImmutableMap.of("key", "value")));
+
+      assertRequestLineEquals(request,
+               "PUT https://identity.blob.core.windows.net/container?restype=container&comp=metadata HTTP/1.1");
+      assertNonPayloadHeadersEqual(request,
+               "x-ms-meta-key: value\n" +
+               "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, null);
+   }
+
+   public void testGetBlob() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "getBlob", String.class, String.class, GetOptions[].class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container", "blob"));
+
+      assertRequestLineEquals(request, "GET https://identity.blob.core.windows.net/container/blob HTTP/1.1");
+      assertNonPayloadHeadersEqual(request, "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ParseBlobFromHeadersAndHttpContent.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, NullOnKeyNotFound.class);
+   }
+
+   public void testSetBlobMetadata() throws SecurityException, NoSuchMethodException, IOException {
+      Invokable<?, ?> method = method(AzureBlobClient.class, "setBlobMetadata", String.class, String.class, Map.class);
+      GeneratedHttpRequest request = processor.createRequest(method, ImmutableList.<Object> of("container", "blob", ImmutableMap.of("key", "value")));
+
+      assertRequestLineEquals(request,
+               "PUT https://identity.blob.core.windows.net/container/blob?comp=metadata HTTP/1.1");
+      assertNonPayloadHeadersEqual(request,
+               "x-ms-meta-key: value\n" +
+               "x-ms-version: 2012-02-12\n");
+      assertPayloadEquals(request, null, null, false);
+
+      assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
+      assertSaxResponseParserClassEquals(method, null);
+      assertFallbackClassEquals(method, null);
+   }
+
+   @Override
+   protected void checkFilters(HttpRequest request) {
+      assertEquals(request.getFilters().size(), 1);
+      assertEquals(request.getFilters().get(0).getClass(), SharedKeyLiteAuthentication.class);
+   }
+
+   @Override
+   public AzureBlobProviderMetadata createProviderMetadata() {
+      return new AzureBlobProviderMetadata();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azureblob/binders/BindAzureBlobMetadataToRequestTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/binders/BindAzureBlobMetadataToRequestTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/binders/BindAzureBlobMetadataToRequestTest.java
index a933805..faec9bb 100644
--- a/providers/azureblob/src/test/java/org/jclouds/azureblob/binders/BindAzureBlobMetadataToRequestTest.java
+++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/binders/BindAzureBlobMetadataToRequestTest.java
@@ -20,7 +20,7 @@ import static org.testng.Assert.assertEquals;
 
 import java.io.File;
 
-import org.jclouds.azureblob.AzureBlobAsyncClient;
+import org.jclouds.azureblob.AzureBlobClient;
 import org.jclouds.azureblob.AzureBlobProviderMetadata;
 import org.jclouds.azureblob.domain.AzureBlob;
 import org.jclouds.http.HttpRequest;
@@ -31,12 +31,8 @@ import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableMap;
 
-/**
- * Tests behavior of {@code BindAzureBlobMetadataToRequest}
- */
-// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
 @Test(groups = "unit", testName = "BindAzureBlobMetadataToRequestTest")
-public class BindAzureBlobMetadataToRequestTest extends BaseAsyncClientTest<AzureBlobAsyncClient> {
+public class BindAzureBlobMetadataToRequestTest extends BaseAsyncClientTest<AzureBlobClient> {
 
    @Test
    public void testPassWithMinimumDetailsAndPayload64MB() {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSignerTest.java
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSignerTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSignerTest.java
index b2ba5f2..024611c 100644
--- a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSignerTest.java
+++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/AzureBlobRequestSignerTest.java
@@ -21,15 +21,15 @@ import static org.testng.Assert.assertEquals;
 import java.io.IOException;
 import java.util.Date;
 
-import org.jclouds.azureblob.AzureBlobAsyncClient;
+import org.jclouds.azureblob.AzureBlobClient;
 import org.jclouds.azureblob.AzureBlobProviderMetadata;
-import org.jclouds.azureblob.config.AzureBlobRestClientModule;
+import org.jclouds.azureblob.config.AzureBlobHttpApiModule;
 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;
@@ -43,7 +43,7 @@ import com.google.inject.Module;
  */
 // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
 @Test(groups = "unit", testName = "AzureBlobRequestSignerTest")
-public class AzureBlobRequestSignerTest extends BaseAsyncClientTest<AzureBlobAsyncClient> {
+public class AzureBlobRequestSignerTest extends BaseAsyncClientTest<AzureBlobClient> {
 
    public AzureBlobRequestSignerTest() {
       // this is base64 decoded in the signer;
@@ -122,11 +122,11 @@ public class AzureBlobRequestSignerTest extends BaseAsyncClientTest<AzureBlobAsy
 
    @Override
    protected Module createModule() {
-      return new TestAzureBlobRestClientModule();
+      return new TestAzureBlobHttpApiModule();
    }
 
-      @ConfiguresRestClient
-   private static final class TestAzureBlobRestClientModule extends AzureBlobRestClientModule {
+      @ConfiguresHttpApi
+   private static final class TestAzureBlobHttpApiModule extends AzureBlobHttpApiModule {
       @Override
       protected void configure() {
          super.configure();

http://git-wip-us.apache.org/repos/asf/jclouds/blob/4c95a578/providers/azureblob/src/test/resources/test_error.xml
----------------------------------------------------------------------
diff --git a/providers/azureblob/src/test/resources/test_error.xml b/providers/azureblob/src/test/resources/test_error.xml
new file mode 100644
index 0000000..6c12fac
--- /dev/null
+++ b/providers/azureblob/src/test/resources/test_error.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Error>
+	<Code>AuthenticationFailed</Code>
+	<Message>Server failed to authenticate the request. Make sure the value
+		of Authorization header is formed correctly including the signature.
+		RequestId:7859e884-e8b9-4ed0-aa62-ac6963b91bf6
+		Time:2009-09-02T23:32:36.7507749Z</Message>
+	<AuthenticationErrorDetail>The MAC signature found in the HTTP request
+		'XEv0NqP+zePZxlrHmxy2F6MiyoRD8LIJt1f/Swgzn1U=' is not the same as any
+		computed signature. Server used following string to sign: 'GET
+
+
+		Wed, 02 Sep 2009 23:32:34 GMT
+		/jclouds/?comp=list'.</AuthenticationErrorDetail>
+</Error>