You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by za...@apache.org on 2014/01/17 21:09:01 UTC

[3/3] git commit: JCLOUDS-299: Added copy method to Object API

JCLOUDS-299: Added copy method to Object API

- Added copy method
- Added CopyObjectException file
- Added SwiftHeaders file
- Updated the Swift error handler
- Added CreateContainerOptions.NONE and updated refs
- Added Region specific configuration for live tests
- Added support for LocationConstants.REGION


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/commit/0a8010be
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/tree/0a8010be
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/diff/0a8010be

Branch: refs/heads/1.7.x
Commit: 0a8010bef6046798122aef3532ebd78aba8315ce
Parents: 4f2fddb
Author: Jeremy Daggett <je...@rackspace.com>
Authored: Tue Jan 7 12:52:04 2014 -0800
Committer: Zack Shoylev <za...@rackspace.com>
Committed: Fri Jan 17 14:05:11 2014 -0600

----------------------------------------------------------------------
 .../openstack/swift/v1/CopyObjectException.java |  51 ++++
 .../openstack/swift/v1/features/ObjectApi.java  |  54 +++-
 .../swift/v1/handlers/SwiftErrorHandler.java    |  17 +-
 .../v1/options/CreateContainerOptions.java      |   1 +
 .../swift/v1/reference/SwiftHeaders.java        |  51 ++++
 .../swift/v1/AuthenticationMockTest.java        |   4 +-
 .../swift/v1/TemporaryUrlSignerLiveTest.java    |   2 +-
 .../swift/v1/TemporaryUrlSignerMockTest.java    |   8 +-
 .../swift/v1/features/AccountApiLiveTest.java   |   6 +-
 .../swift/v1/features/AccountApiMockTest.java   |  22 +-
 .../swift/v1/features/BulkApiLiveTest.java      |  12 +-
 .../swift/v1/features/BulkApiMockTest.java      |   4 +-
 .../swift/v1/features/ContainerApiLiveTest.java |  16 +-
 .../swift/v1/features/ContainerApiMockTest.java |  52 ++--
 .../swift/v1/features/ObjectApiLiveTest.java    |  91 +++++--
 .../swift/v1/features/ObjectApiMockTest.java    | 101 ++++++--
 .../features/StaticLargeObjectApiLiveTest.java  |  12 +-
 .../features/StaticLargeObjectApiMockTest.java  |  12 +-
 .../swift/v1/internal/BaseSwiftApiLiveTest.java |  21 +-
 openstack-swift/src/test/resources/access.json  | 249 +++++++++++++++++++
 20 files changed, 657 insertions(+), 129 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/CopyObjectException.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/CopyObjectException.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/CopyObjectException.java
new file mode 100644
index 0000000..9258662
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/CopyObjectException.java
@@ -0,0 +1,51 @@
+/*
+ * 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.openstack.swift.v1;
+
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.rest.ResourceNotFoundException;
+
+/**
+ * Thrown when an object cannot be copied.
+ *
+ * @see {@link SwiftErrorHandler#handleError(HttpCommand, HttpResponse)}
+ *  
+ * @author Everett Toews
+ * @author Jeremy Daggett
+ */
+public class CopyObjectException extends ResourceNotFoundException {
+
+   private String sourcePath;
+   private String destinationPath;
+
+   public CopyObjectException(String sourcePath, String destinationPath, String message) {
+      super(String.format("Either the source path '%s' or the destination path '%s' was not found. " +
+      		"(message: %s)", sourcePath, destinationPath, message));
+      this.sourcePath = sourcePath;
+      this.destinationPath = destinationPath;
+   }
+
+   public String getSourcePath() {
+      return sourcePath;
+   }
+
+   public String getDestinationPath() {
+      return destinationPath;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
index 14ce2f4..374bfa6 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
@@ -17,6 +17,7 @@
 package org.jclouds.openstack.swift.v1.features;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_COPY_FROM;
 
 import java.util.Map;
 
@@ -33,10 +34,12 @@ import javax.ws.rs.PathParam;
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
+import org.jclouds.blobstore.BlobStoreFallbacks.FalseOnContainerNotFound;
 import org.jclouds.http.options.GetOptions;
 import org.jclouds.io.Payload;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.swift.v1.CopyObjectException;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindObjectMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveObjectMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.SetPayload;
@@ -48,6 +51,7 @@ import org.jclouds.openstack.swift.v1.functions.ParseObjectListFromResponse;
 import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
 import org.jclouds.rest.annotations.BinderParam;
 import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.Headers;
 import org.jclouds.rest.annotations.QueryParams;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.ResponseParser;
@@ -64,7 +68,10 @@ public interface ObjectApi {
    /**
     * Lists up to 10,000 objects.
     * 
-    * @return a list of existing storage objects ordered by name or null.
+    * @param options
+    *          options to control the output list.
+    *          
+    * @return an {@link ObjectList} of {@link SwiftObject} ordered by name or null.
     */
    @Named("ListObjects")
    @GET
@@ -103,7 +110,7 @@ public interface ObjectApi {
     * 
     * @param objectName
     *           corresponds to {@link SwiftObject#name()}.
-    * @return the Object or null, if not found.
+    * @return the {@link SwiftObject} or null, if not found.
     * 
     * @see <a
     *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/retrieve-object-metadata.html">
@@ -140,18 +147,18 @@ public interface ObjectApi {
    SwiftObject get(@PathParam("objectName") String objectName, GetOptions options);
 
    /**
-    * Creates or updates the Object metadata.
+    * Creates or updates the metadata for a {@link SwiftObject}.
     * 
     * @param objectName
     *           corresponds to {@link SwiftObject#name()}.
     * @param metadata
-    *           the Object metadata to create or update.
+    *           the metadata to create or update.
     * 
     * @see <a
     *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/Update_Container_Metadata-d1e1900.html">
     *      Create or Update Object Metadata API</a>
     * 
-    * @return <code>true</code> if the Object Metadata was successfully created
+    * @return {@code true} if the metadata was successfully created
     *         or updated, false if not.
     */
    @Named("UpdateObjectMetadata")
@@ -162,15 +169,14 @@ public interface ObjectApi {
          @BinderParam(BindObjectMetadataToHeaders.class) Map<String, String> metadata);
 
    /**
-    * Deletes Object metadata.
+    * Deletes the metadata from a {@link SwiftObject}.
     * 
     * @param objectName
     *           corresponds to {@link SwiftObject#name()}.
     * @param metadata
-    *           the Object metadata to delete.
+    *           corresponds to {@link SwiftObject#metadata()}.
     * 
-    * @return <code>true</code> if the Object Metadata was successfully deleted,
-    *         false if not.
+    * @return {@code true} if the metadata was successfully deleted, false if not.
     * 
     * @see <a
     *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/delete-object-metadata.html">
@@ -184,7 +190,7 @@ public interface ObjectApi {
          @BinderParam(BindRemoveObjectMetadataToHeaders.class) Map<String, String> metadata);
 
    /**
-    * Deletes a object, if present.
+    * Deletes an object, if present.
     * 
     * @param objectName
     *           corresponds to {@link SwiftObject#name()}.
@@ -197,4 +203,32 @@ public interface ObjectApi {
    @Fallback(VoidOnNotFoundOr404.class)
    @Path("/{objectName}")
    void delete(@PathParam("objectName") String objectName);
+
+   /**
+    * Copies an object from one container to another. Please note that this 
+    * is a server side copy.
+    * 
+    * @param destinationObject
+    *           the destination object name.
+    * @param sourceContainer
+    *           the source container name.
+    * @param sourceObject
+    *           the source object name.
+    * @return {@code true} if the object was successfully copied, false if not.
+    * 
+    * @throws CopyObjectException if the source or destination container do not exist
+    * 
+    * @see <a
+    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/copy-object.html">
+    *      Copy Object API</a>
+    */
+   @Named("CopyObject")
+   @PUT
+   @Path("/{destinationObject}")
+   @Headers(keys = OBJECT_COPY_FROM, values = "/{sourceContainer}/{sourceObject}")
+   @Fallback(FalseOnContainerNotFound.class)
+   boolean copy(@PathParam("destinationObject") String destinationObject,
+                @PathParam("sourceContainer") String sourceContainer,
+                @PathParam("sourceObject") String sourceObject);
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java
index f94f4a8..2fe469e 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/handlers/SwiftErrorHandler.java
@@ -27,6 +27,8 @@ import org.jclouds.http.HttpCommand;
 import org.jclouds.http.HttpErrorHandler;
 import org.jclouds.http.HttpResponse;
 import org.jclouds.http.HttpResponseException;
+import org.jclouds.openstack.swift.v1.CopyObjectException;
+import org.jclouds.openstack.swift.v1.reference.SwiftHeaders;
 import org.jclouds.rest.AuthorizationException;
 
 // TODO: is there error spec someplace? let's type errors, etc.
@@ -49,10 +51,21 @@ public class SwiftErrorHandler implements HttpErrorHandler {
             exception = new AuthorizationException(exception.getMessage(), exception);
             break;
          case 404:
-            if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
+            Exception oldException = exception;         
+            String sourcePath = command.getCurrentRequest().getFirstHeaderOrNull(SwiftHeaders.OBJECT_COPY_FROM);
+            if (sourcePath != null) {
+               // the path returned here is in the form "/v1/tenant-id/destContainer/destObject"
+               String path = command.getCurrentRequest().getEndpoint().getPath();
+               int startOfDestinationPath = path.lastIndexOf("/", path.lastIndexOf("/") - 1);
+               // get the "/destContainer/destObject" portion of the path
+               String destinationPath = path.substring(startOfDestinationPath);
+               
+               exception = new CopyObjectException(sourcePath, destinationPath, message);
+               exception.initCause(oldException);
+            } else if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
                String path = command.getCurrentRequest().getEndpoint().getPath();
                Matcher matcher = CONTAINER_PATH.matcher(path);
-               Exception oldException = exception;
+               
                if (matcher.find()) {
                   exception = new ContainerNotFoundException(matcher.group(1), message);
                   exception.initCause(oldException);

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/CreateContainerOptions.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/CreateContainerOptions.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/CreateContainerOptions.java
index 46506bb..fc8f9c8 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/CreateContainerOptions.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/CreateContainerOptions.java
@@ -29,6 +29,7 @@ import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders;
  * @see ContainerApi#createIfAbsent
  */
 public class CreateContainerOptions extends BaseHttpRequestOptions {
+   public static final CreateContainerOptions NONE = new CreateContainerOptions();
 
    /** corresponds to {@link Container#metadata()} */
    public CreateContainerOptions metadata(Map<String, String> metadata) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/reference/SwiftHeaders.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/reference/SwiftHeaders.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/reference/SwiftHeaders.java
new file mode 100644
index 0000000..e0c9348
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/reference/SwiftHeaders.java
@@ -0,0 +1,51 @@
+/*
+ * 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.openstack.swift.v1.reference;
+
+/**
+ * Common headers in Swift.
+ * 
+ * @author Jeremy Daggett
+ */
+public interface SwiftHeaders {
+
+   String USER_METADATA_PREFIX = "X-Object-Meta-"; 
+	
+   String ACCOUNT_TEMPORARY_URL_KEY = "X-Account-Meta-Temp-Url-Key";
+   String ACCOUNT_BYTES_USED = "X-Account-Bytes-Used";
+   String ACCOUNT_CONTAINER_COUNT = "X-Account-Container-Count";
+
+   String CONTAINER_BYTES_USED = "X-Container-Bytes-Used";
+   String CONTAINER_OBJECT_COUNT = "X-Container-Object-Count";
+   String CONTAINER_METADATA_PREFIX = "X-Container-Meta-";
+   String CONTAINER_DELETE_METADATA_PREFIX = "X-Remove-Container-Meta-";
+
+   String CONTAINER_READ = "X-Container-Read";
+   String CONTAINER_WRITE = "X-Container-Write";
+   
+   String CONTAINER_WEB_INDEX = "X-Container-Meta-Web-Index"; 
+   String CONTAINER_WEB_ERROR = "X-Container-Meta-Web-Error"; 
+   String CONTAINER_WEB_LISTINGS = "X-Container-Meta-Web-Listings";
+   String CONTAINER_WEB_LISTINGS_CSS = "X-Container-Meta-Web-Listings-CSS";    
+   
+   String OBJECT_COPY_FROM = "X-Copy-From";
+   String OBJECT_DELETE_AFTER = "X-Delete-After";
+   String OBJECT_DELETE_AT = "X-Delete-At";
+   /** Get the newest version of the object for GET and HEAD requests */
+   String OBJECT_NEWEST = "X-Newest";
+   String OBJECT_VERSIONS_LOCATION = "X-Versions-Location";
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/AuthenticationMockTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/AuthenticationMockTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/AuthenticationMockTest.java
index 0514684..93f387b 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/AuthenticationMockTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/AuthenticationMockTest.java
@@ -51,8 +51,8 @@ public class AuthenticationMockTest extends BaseOpenStackMockTest<SwiftApi> {
    @Test(dataProvider = "jclouds.keystone.credential-type")
    public void authenticateCredentialType(String credentialType, String expectedPost) throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(accountResponse());
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(accountResponse()));
 
       try {
          Properties overrides = new Properties();

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerLiveTest.java
index f2ba78f..733563c 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerLiveTest.java
@@ -73,7 +73,7 @@ public class TemporaryUrlSignerLiveTest extends BaseSwiftApiLiveTest {
       String key = UUID.randomUUID().toString();
       for (String regionId : api.configuredRegions()) {
          api.accountApiInRegion(regionId).updateTemporaryUrlKey(key);
-         api.containerApiInRegion(regionId).createIfAbsent(containerName, new CreateContainerOptions());
+         api.containerApiInRegion(regionId).createIfAbsent(containerName, CreateContainerOptions.NONE);
          api.objectApiInRegionForContainer(regionId, containerName) //
                .replace(name, newStringPayload("swifty"), ImmutableMap.<String, String> of());
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerMockTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerMockTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerMockTest.java
index f7ebb7d..0f856ba 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerMockTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TemporaryUrlSignerMockTest.java
@@ -35,8 +35,8 @@ public class TemporaryUrlSignerMockTest extends BaseOpenStackMockTest<SwiftApi>
 
    public void whenAccountApiHasKey() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(accountResponse().addHeader("X-Account-Meta-Temp-URL-Key", "mykey"));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(accountResponse().addHeader("X-Account-Meta-Temp-URL-Key", "mykey")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -57,8 +57,8 @@ public class TemporaryUrlSignerMockTest extends BaseOpenStackMockTest<SwiftApi>
    @Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = ".*returned a null temporaryUrlKey!")
    public void whenAccountApiDoesntHaveKey() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(accountResponse());
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(accountResponse()));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiLiveTest.java
index a1b388e..31eff6e 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiLiveTest.java
@@ -34,7 +34,7 @@ import com.google.common.collect.ImmutableMap;
 public class AccountApiLiveTest extends BaseSwiftApiLiveTest {
 
    public void get() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          AccountApi accountApi = api.accountApiInRegion(regionId);
          Account account = accountApi.get();
 
@@ -46,7 +46,7 @@ public class AccountApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void updateMetadata() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          AccountApi accountApi = api.accountApiInRegion(regionId);
 
          Map<String, String> meta = ImmutableMap.of("MyAdd1", "foo", "MyAdd2", "bar");
@@ -58,7 +58,7 @@ public class AccountApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void deleteMetadata() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          AccountApi accountApi = api.accountApiInRegion(regionId);
 
          Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiMockTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiMockTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiMockTest.java
index 41dd1c7..2c5a9b2 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiMockTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/AccountApiMockTest.java
@@ -22,9 +22,9 @@ import static org.testng.Assert.assertTrue;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
 import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.Account;
+import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
 import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableMap;
@@ -41,11 +41,11 @@ public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    /** upper-cases first char, and lower-cases rest!! **/
    public void getKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(accountResponse() //
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(accountResponse() //
             // note silly casing
             .addHeader("X-Account-Meta-Apiname", "swift") //
-            .addHeader("X-Account-Meta-Apiversion", "v1.1"));
+            .addHeader("X-Account-Meta-Apiversion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -68,10 +68,10 @@ public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void updateMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(accountResponse() //
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(accountResponse() //
             .addHeader("X-Account-Meta-ApiName", "swift") //
-            .addHeader("X-Account-Meta-ApiVersion", "v1.1"));
+            .addHeader("X-Account-Meta-ApiVersion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -92,8 +92,8 @@ public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void updateTemporaryUrlKey() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(accountResponse());
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(accountResponse()));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -112,8 +112,8 @@ public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void deleteMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(accountResponse());
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(accountResponse()));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiLiveTest.java
index 70f5c2f..39341fd 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiLiveTest.java
@@ -49,7 +49,7 @@ public class BulkApiLiveTest extends BaseSwiftApiLiveTest {
    private String containerName = getClass().getSimpleName();
 
    public void notPresentWhenDeleting() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          BulkDeleteResponse deleteResponse = api.bulkApiInRegion(regionId).bulkDelete(
                ImmutableList.of(UUID.randomUUID().toString()));
          assertEquals(deleteResponse.deleted(), 0);
@@ -59,7 +59,7 @@ public class BulkApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void extractArchive() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          ExtractArchiveResponse extractResponse = api.bulkApiInRegion(regionId).extractArchive(containerName,
                Payloads.newPayload(tarGz), "tar.gz");
          assertEquals(extractResponse.created(), OBJECT_COUNT);
@@ -76,7 +76,7 @@ public class BulkApiLiveTest extends BaseSwiftApiLiveTest {
 
    @Test(dependsOnMethods = "extractArchive")
    public void bulkDelete() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          BulkDeleteResponse deleteResponse = api.bulkApiInRegion(regionId).bulkDelete(paths);
          assertEquals(deleteResponse.deleted(), OBJECT_COUNT);
          assertEquals(deleteResponse.notFound(), 0);
@@ -92,9 +92,9 @@ public class BulkApiLiveTest extends BaseSwiftApiLiveTest {
    @BeforeClass(groups = "live")
    public void setup() {
       super.setup();
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          boolean created = api.containerApiInRegion(regionId).createIfAbsent(containerName,
-               new CreateContainerOptions());
+               CreateContainerOptions.NONE);
          if (!created) {
             deleteAllObjectsInContainer(regionId, containerName);
          }
@@ -115,7 +115,7 @@ public class BulkApiLiveTest extends BaseSwiftApiLiveTest {
    @Override
    @AfterClass(groups = "live")
    public void tearDown() {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          deleteAllObjectsInContainer(regionId, containerName);
          api.containerApiInRegion(regionId).deleteIfEmpty(containerName);
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiMockTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiMockTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiMockTest.java
index d73e448..69ce5a1 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiMockTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/BulkApiMockTest.java
@@ -47,8 +47,8 @@ public class BulkApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
       byte[] tarGz = ByteStreams.toByteArray(files.as(TarGzExporter.class).exportAsInputStream());
 
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(201).setBody("{\"Number Files Created\": 10, \"Errors\": []}"));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201).setBody("{\"Number Files Created\": 10, \"Errors\": []}")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
index 7a21b2c..e28ca8e 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiLiveTest.java
@@ -44,7 +44,7 @@ public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
 
    @Test
    public void list() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          ContainerApi containerApi = api.containerApiInRegion(regionId);
          FluentIterable<Container> response = containerApi.listFirstPage();
          assertNotNull(response);
@@ -57,7 +57,7 @@ public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void get() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          Container container = api.containerApiInRegion(regionId).get(name);
          assertEquals(container.name(), name);
          assertTrue(container.objectCount() == 0);
@@ -67,7 +67,7 @@ public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
 
    public void listAt() throws Exception {
       String lexicographicallyBeforeName = name.substring(0, name.length() - 1);
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          Container container = api.containerApiInRegion(regionId).listAt(lexicographicallyBeforeName).get(0);
          assertEquals(container.name(), name);
          assertTrue(container.objectCount() == 0);
@@ -76,7 +76,7 @@ public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void updateMetadata() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          ContainerApi containerApi = api.containerApiInRegion(regionId);
 
          Map<String, String> meta = ImmutableMap.of("MyAdd1", "foo", "MyAdd2", "bar");
@@ -88,7 +88,7 @@ public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void deleteMetadata() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          ContainerApi containerApi = api.containerApiInRegion(regionId);
 
          Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");
@@ -118,15 +118,15 @@ public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
    @BeforeClass(groups = "live")
    public void setup() {
       super.setup();
-      for (String regionId : api.configuredRegions()) {
-         api.containerApiInRegion(regionId).createIfAbsent(name, new CreateContainerOptions());
+      for (String regionId : regions) {
+         api.containerApiInRegion(regionId).createIfAbsent(name, CreateContainerOptions.NONE);
       }
    }
 
    @Override
    @AfterClass(groups = "live")
    public void tearDown() {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          api.containerApiInRegion(regionId).deleteIfEmpty(name);
       }
       super.tearDown();

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
index 63f9d80..b52122d 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
@@ -47,8 +47,8 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void listFirstPage() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setBody(containerList));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(containerList)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -74,8 +74,8 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void listAt() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setBody(containerList));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(containerList)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -101,12 +101,12 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void createIfAbsent() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(201));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
-         assertTrue(api.containerApiInRegion("DFW").createIfAbsent("myContainer", new CreateContainerOptions()));
+         assertTrue(api.containerApiInRegion("DFW").createIfAbsent("myContainer", CreateContainerOptions.NONE));
 
          assertEquals(server.getRequestCount(), 2);
          assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
@@ -120,8 +120,8 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void createWithOptions() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(201));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -143,12 +143,12 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void alreadyCreated() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(202));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(202)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
-         assertFalse(api.containerApiInRegion("DFW").createIfAbsent("myContainer", new CreateContainerOptions()));
+         assertFalse(api.containerApiInRegion("DFW").createIfAbsent("myContainer", CreateContainerOptions.NONE));
 
          assertEquals(server.getRequestCount(), 2);
          assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
@@ -163,11 +163,11 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    /** upper-cases first char, and lower-cases rest!! **/
    public void getKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(containerResponse() //
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(containerResponse() //
             // note silly casing
             .addHeader("X-Container-Meta-Apiname", "swift") //
-            .addHeader("X-Container-Meta-Apiversion", "v1.1"));
+            .addHeader("X-Container-Meta-Apiversion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -190,10 +190,10 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void updateMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(containerResponse() //
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(containerResponse() //
             .addHeader("X-Container-Meta-ApiName", "swift") //
-            .addHeader("X-Container-Meta-ApiVersion", "v1.1"));
+            .addHeader("X-Container-Meta-ApiVersion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -214,8 +214,8 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void deleteMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(containerResponse());
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(containerResponse()));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -236,8 +236,8 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void deleteIfEmpty() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(204));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(204)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -255,8 +255,8 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void alreadyDeleted() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(404));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -275,8 +275,8 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    @Test(expectedExceptions = IllegalStateException.class)
    public void deleteWhenNotEmpty() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(409));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(409)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
index cfc7192..4559983 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
@@ -32,11 +32,15 @@ import java.util.Map.Entry;
 import java.util.concurrent.TimeUnit;
 
 import org.jclouds.http.options.GetOptions;
+import org.jclouds.io.Payload;
+import org.jclouds.io.Payloads;
+import org.jclouds.openstack.swift.v1.CopyObjectException;
 import org.jclouds.openstack.swift.v1.domain.ObjectList;
 import org.jclouds.openstack.swift.v1.domain.SwiftObject;
 import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
 import org.jclouds.openstack.swift.v1.options.CreateContainerOptions;
 import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.util.Strings2;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -48,13 +52,71 @@ import com.google.common.collect.ImmutableMap;
  */
 @Test(groups = "live", testName = "ObjectApiLiveTest")
 public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
-
    private String name = getClass().getSimpleName();
    private String containerName = getClass().getSimpleName() + "Container";
+   
+   public void copyObject() throws Exception {
+      for (String regionId : regions) {               
+         // source
+         String sourceContainer = "src" + containerName;
+         String sourceObject = "original.txt";
+         String badSource = "badSource";
+         
+         // destination
+         String destinationContainer = "dest" + containerName;
+         String destinationObject = "copy.txt";
+         String destinationPath = "/" + destinationContainer + "/" + destinationObject;
+         
+         String stringPayload = "Hello World";
+         Payload data = Payloads.newPayload(stringPayload);
+         
+         ContainerApi containerApi = api.containerApiInRegion(regionId);
+         
+         // create source and destination dirs
+         containerApi.createIfAbsent(sourceContainer, CreateContainerOptions.NONE);
+         containerApi.createIfAbsent(destinationContainer, CreateContainerOptions.NONE);
+         
+         // get the api for this region and container
+         ObjectApi srcApi = api.objectApiInRegionForContainer(regionId, sourceContainer);
+         ObjectApi destApi = api.objectApiInRegionForContainer(regionId, destinationContainer);
+         
+         // Create source object 
+         assertNotNull(srcApi.replace(sourceObject, data, ImmutableMap.<String, String> of()));
+         SwiftObject object = srcApi.get(sourceObject, GetOptions.NONE);
+         checkObject(object);
+
+         // Create the destination object
+         assertNotNull(destApi.replace(destinationObject, data, ImmutableMap.<String, String> of()));
+         object = destApi.get(destinationObject, GetOptions.NONE);
+         checkObject(destApi.get(destinationObject, GetOptions.NONE));
+
+         // check the copy operation 
+         assertTrue(destApi.copy(destinationObject, sourceContainer, sourceObject));
+         assertNotNull(destApi.head(destinationObject));
+         
+         // now get a real SwiftObject
+         SwiftObject destSwiftObject = destApi.get(destinationObject, GetOptions.NONE);
+         assertEquals(Strings2.toString(destSwiftObject.payload()), stringPayload);
+         
+         // test exception thrown on bad source name
+         try {
+            destApi.copy(destinationObject, badSource, sourceObject);
+            fail("Expected CopyObjectException");
+         } catch (CopyObjectException e) {             
+            assertEquals(e.getSourcePath(), "/" + badSource + "/" + sourceObject);
+            assertEquals(e.getDestinationPath(), destinationPath);
+         }
+
+         deleteAllObjectsInContainer(regionId, sourceContainer);
+         containerApi.deleteIfEmpty(sourceContainer);
+
+         deleteAllObjectsInContainer(regionId, destinationContainer);
+         containerApi.deleteIfEmpty(destinationContainer);
+      }
+   }
 
-   @Test
    public void list() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName);
          ObjectList response = objectApi.list(new ListContainerOptions());
          assertEquals(response.container(), api.containerApiInRegion(regionId).get(containerName));
@@ -75,7 +137,7 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void metadata() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).head(name);
          assertEquals(object.name(), name);
          checkObject(object);
@@ -84,7 +146,7 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void get() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).get(name, GetOptions.NONE);
          assertEquals(object.name(), name);
          checkObject(object);
@@ -93,7 +155,7 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void privateByDefault() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).head(name);
          try {
             object.uri().toURL().openStream();
@@ -104,7 +166,7 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void getOptions() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).get(name, tail(1));
          assertEquals(object.name(), name);
          checkObject(object);
@@ -114,7 +176,7 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
 
    public void listOptions() throws Exception {
       String lexicographicallyBeforeName = name.substring(0, name.length() - 1);
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName)
                .list(marker(lexicographicallyBeforeName)).get(0);
          assertEquals(object.name(), name);
@@ -123,19 +185,17 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
    }
 
    public void updateMetadata() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName);
 
          Map<String, String> meta = ImmutableMap.of("MyAdd1", "foo", "MyAdd2", "bar");
-
          assertTrue(objectApi.updateMetadata(name, meta));
-
          containerHasMetadata(objectApi, name, meta);
       }
    }
 
    public void deleteMetadata() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName);
 
          Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");
@@ -165,8 +225,8 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
    @BeforeClass(groups = "live")
    public void setup() {
       super.setup();
-      for (String regionId : api.configuredRegions()) {
-         api.containerApiInRegion(regionId).createIfAbsent(containerName, new CreateContainerOptions());
+      for (String regionId : regions) {
+         api.containerApiInRegion(regionId).createIfAbsent(containerName, CreateContainerOptions.NONE);
          api.objectApiInRegionForContainer(regionId, containerName).replace(name, newStringPayload("swifty"),
                ImmutableMap.<String, String> of());
       }
@@ -175,7 +235,8 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
    @Override
    @AfterClass(groups = "live")
    public void tearDown() {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
+         deleteAllObjectsInContainer(regionId, containerName);
          api.objectApiInRegionForContainer(regionId, containerName).delete(name);
          api.containerApiInRegion(regionId).deleteIfEmpty(containerName);
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
index d8dfb1e..7ceb21a 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiMockTest.java
@@ -20,23 +20,35 @@ import static com.google.common.base.Charsets.US_ASCII;
 import static com.google.common.net.HttpHeaders.RANGE;
 import static org.jclouds.http.options.GetOptions.Builder.tail;
 import static org.jclouds.io.Payloads.newStringPayload;
+import static org.jclouds.openstack.swift.v1.features.ContainerApiMockTest.containerResponse;
 import static org.jclouds.openstack.swift.v1.options.ListContainerOptions.Builder.marker;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_COPY_FROM;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
-import static org.jclouds.openstack.swift.v1.features.ContainerApiMockTest.containerResponse;
 
+import java.io.IOException;
 import java.net.URI;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import javax.inject.Named;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import org.jclouds.blobstore.BlobStoreFallbacks.FalseOnContainerNotFound;
 import org.jclouds.date.internal.SimpleDateFormatDateService;
 import org.jclouds.io.Payload;
 import org.jclouds.io.Payloads;
-import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
+import org.jclouds.openstack.swift.v1.CopyObjectException;
 import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.ObjectList;
 import org.jclouds.openstack.swift.v1.domain.SwiftObject;
 import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.openstack.swift.v1.reference.SwiftHeaders;
+import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.Headers;
 import org.jclouds.util.Strings2;
 import org.testng.annotations.Test;
 
@@ -83,10 +95,10 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void list() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(containerResponse() //
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(containerResponse() //
             .addHeader("X-Container-Read", ".r:*,.rlistings") //
-            .setBody(objectList));
+            .setBody(objectList)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -106,8 +118,8 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void listOptions() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(containerResponse().setBody(objectList));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(containerResponse().setBody(objectList)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -125,10 +137,10 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void replace() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse() //
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse() //
             .setResponseCode(201) //
-            .addHeader("ETag", "d9f5eb4bba4e2f2f046e54611bc8196b"));
+            .addHeader("ETag", "d9f5eb4bba4e2f2f046e54611bc8196b")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -153,11 +165,11 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    /** upper-cases first char, and lower-cases rest!! **/
    public void headKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(objectResponse() //
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(objectResponse() //
             // note silly casing
             .addHeader("X-Object-Meta-Apiname", "swift") //
-            .addHeader("X-Object-Meta-Apiversion", "v1.1"));
+            .addHeader("X-Object-Meta-Apiversion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -183,11 +195,11 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void get() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(objectResponse() //
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(objectResponse() //
             // note silly casing
             .addHeader("X-Object-Meta-Apiname", "swift") //
-            .addHeader("X-Object-Meta-Apiversion", "v1.1"));
+            .addHeader("X-Object-Meta-Apiversion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -216,10 +228,10 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void updateMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(objectResponse() //
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(objectResponse() //
             .addHeader("X-Object-Meta-ApiName", "swift") //
-            .addHeader("X-Object-Meta-ApiVersion", "v1.1"));
+            .addHeader("X-Object-Meta-ApiVersion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -240,8 +252,8 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void deleteMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(objectResponse());
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(objectResponse()));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -262,8 +274,8 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void delete() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(204));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(204)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -281,8 +293,8 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    public void alreadyDeleted() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(404));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -297,7 +309,44 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          server.shutdown();
       }
    }
-
+   
+   public void copyObject() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)
+            .addHeader(SwiftHeaders.OBJECT_COPY_FROM, "/bar/foo.txt")));
+      try {
+         SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+         assertTrue(api.objectApiInRegionForContainer("DFW", "foo")
+            .copy("bar.txt", "bar", "foo.txt"));
+              
+         assertEquals(server.getRequestCount(), 2);
+         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+         
+         RecordedRequest copyRequest = server.takeRequest();
+         assertEquals(copyRequest.getRequestLine(),
+               "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/foo/bar.txt HTTP/1.1");
+      } finally {
+         server.shutdown();
+      }
+   }
+   
+   @Test(expectedExceptions = CopyObjectException.class)
+   public void copyObjectFail() throws InterruptedException, IOException {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)
+            .addHeader(SwiftHeaders.OBJECT_COPY_FROM, "/bogus/foo.txt")));
+      
+      try {
+         SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
+         // the following line will throw the CopyObjectException
+         api.objectApiInRegionForContainer("DFW", "foo").copy("bar.txt", "bogus", "foo.txt"); 
+      } finally {
+         server.shutdown();
+      }  
+   }
+   
    private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
 
    public static MockResponse objectResponse() {

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiLiveTest.java
index 36af318..eb08f76 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiLiveTest.java
@@ -45,13 +45,13 @@ public class StaticLargeObjectApiLiveTest extends BaseSwiftApiLiveTest {
    private byte[] megOf2s;
 
    public void notPresentWhenDeleting() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          api.staticLargeObjectApiInRegionForContainer(regionId, containerName).delete(UUID.randomUUID().toString());
       }
    }
 
    public void replaceManifest() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName);
          String etag1s = objectApi.replace(name + "/1", newPayload(megOf1s), ImmutableMap.<String, String> of());
          assertMegabyteAndETagMatches(regionId, name + "/1", etag1s);
@@ -85,7 +85,7 @@ public class StaticLargeObjectApiLiveTest extends BaseSwiftApiLiveTest {
 
    @Test(dependsOnMethods = "replaceManifest")
    public void delete() throws Exception {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          api.staticLargeObjectApiInRegionForContainer(regionId, containerName).delete(name);
          assertEquals(api.containerApiInRegion(regionId).get(containerName).objectCount(), 0);
       }
@@ -95,9 +95,9 @@ public class StaticLargeObjectApiLiveTest extends BaseSwiftApiLiveTest {
    @BeforeClass(groups = "live")
    public void setup() {
       super.setup();
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          boolean created = api.containerApiInRegion(regionId).createIfAbsent(containerName,
-               new CreateContainerOptions());
+               CreateContainerOptions.NONE);
          if (!created) {
             deleteAllObjectsInContainer(regionId, containerName);
          }
@@ -113,7 +113,7 @@ public class StaticLargeObjectApiLiveTest extends BaseSwiftApiLiveTest {
    @Override
    @AfterClass(groups = "live")
    public void tearDown() {
-      for (String regionId : api.configuredRegions()) {
+      for (String regionId : regions) {
          deleteAllObjectsInContainer(regionId, containerName);
          api.containerApiInRegion(regionId).deleteIfEmpty(containerName);
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiMockTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiMockTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiMockTest.java
index 529d7be..4da10a9 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiMockTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApiMockTest.java
@@ -35,8 +35,8 @@ public class StaticLargeObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi
 
    public void replaceManifest() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().addHeader(HttpHeaders.ETAG, "\"abcd\""));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().addHeader(HttpHeaders.ETAG, "\"abcd\"")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -71,8 +71,8 @@ public class StaticLargeObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi
 
    public void delete() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(204));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(204)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -90,8 +90,8 @@ public class StaticLargeObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi
 
    public void alreadyDeleted() throws Exception {
       MockWebServer server = mockOpenStackServer();
-      server.enqueue(new MockResponse().setBody(accessRackspace));
-      server.enqueue(new MockResponse().setResponseCode(404));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
index 8d8166e..239177c 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
@@ -20,28 +20,47 @@ import static com.google.common.base.Preconditions.checkState;
 
 import java.util.List;
 import java.util.Properties;
+import java.util.Set;
 
 import org.jclouds.apis.BaseApiLiveTest;
+import org.jclouds.location.reference.LocationConstants;
 import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
 import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.BulkDeleteResponse;
 import org.jclouds.openstack.swift.v1.domain.ObjectList;
 import org.jclouds.openstack.swift.v1.domain.SwiftObject;
 import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.testng.annotations.BeforeClass;
 
 import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 
 public class BaseSwiftApiLiveTest extends BaseApiLiveTest<SwiftApi> {
 
+   protected Set<String> regions;
+   
    public BaseSwiftApiLiveTest() {
       provider = "openstack-swift";
    }
-
+   
+   @Override
+   @BeforeClass(groups = "live")
+   public void setup() {
+      super.setup();
+      String providedRegion = System.getProperty("test." + LocationConstants.PROPERTY_REGION);
+      if (providedRegion != null) {
+        regions = ImmutableSet.of(providedRegion);
+      } else {
+        regions = api.configuredRegions();
+      }
+   }
+   
    @Override
    protected Properties setupProperties() {
       Properties props = super.setupProperties();
       setIfTestSystemPropertyPresent(props, KeystoneProperties.CREDENTIAL_TYPE);
+      setIfTestSystemPropertyPresent(props, LocationConstants.PROPERTY_REGION);
       return props;
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/0a8010be/openstack-swift/src/test/resources/access.json
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/resources/access.json b/openstack-swift/src/test/resources/access.json
new file mode 100644
index 0000000..8e0a69c
--- /dev/null
+++ b/openstack-swift/src/test/resources/access.json
@@ -0,0 +1,249 @@
+{
+    "access":{
+        "token":{
+            "id":"bb03a23aa8271291a7aaa9aaa2aaaaaa",
+            "expires":"2013-08-02T16:55:24.229-05:00",
+            "tenant":{
+                "id":"888888",
+                "name":"888888"
+            },
+            "RAX-AUTH:authenticatedBy":[
+                "PASSWORD"
+            ]
+        },
+        "serviceCatalog":[
+            {
+                "name":"cloudFilesCDN",
+                "endpoints":[
+                    {
+                        "region":"ORD",
+                        "tenantId":"MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                        "publicURL":"URL/v1\/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9"
+                    },
+                    {
+                        "region":"DFW",
+                        "tenantId":"MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                        "publicURL":"URL/v1\/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9"
+                    },
+                    {
+                        "region":"SYD",
+                        "tenantId":"MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                        "publicURL":"URL/v1\/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9"
+                    }
+                ],
+                "type":"rax:object-cdn"
+            },
+            {
+                "name":"cloudFiles",
+                "endpoints":[
+                    {
+                        "region":"ORD",
+                        "tenantId":"MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                        "publicURL":"URL/v1\/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                        "internalURL":"URL/v1\/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9"
+                    },
+                    {
+                        "region":"DFW",
+                        "tenantId":"MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                        "publicURL":"URL/v1\/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                        "internalURL":"URL/v1\/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9"
+                    },
+                    {
+                        "region":"SYD",
+                        "tenantId":"MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                        "publicURL":"URL/v1\/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                        "internalURL":"URL/v1\/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9"
+                    }
+                ],
+                "type":"object-store"
+            },
+            {
+                "name":"cloudLoadBalancers",
+                "endpoints":[
+                    {
+                        "region":"SYD",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888"
+                    },
+                    {
+                        "region":"DFW",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888"
+                    },
+                    {
+                        "region":"ORD",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888"
+                    }
+                ],
+                "type":"rax:load-balancer"
+            },
+            {
+                "name":"cloudDatabases",
+                "endpoints":[
+                    {
+                        "region":"SYD",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888"
+                    },
+                    {
+                        "region":"DFW",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888"
+                    },
+                    {
+                        "region":"ORD",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888"
+                    }
+                ],
+                "type":"rax:database"
+            },
+            {
+                "name":"cloudBlockStorage",
+                "endpoints":[
+                    {
+                        "region":"SYD",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1\/888888"
+                    },
+                    {
+                        "region":"DFW",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1\/888888"
+                    },
+                    {
+                        "region":"ORD",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1\/888888"
+                    }
+                ],
+                "type":"volume"
+            },
+            {
+                "name":"cloudServersOpenStack",
+                "endpoints":[
+                    {
+                        "region":"SYD",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v2\/888888",
+                        "versionInfo":"https:\/\/syd.servers.api.rackspacecloud.com\/v2",
+                        "versionList":"https:\/\/syd.servers.api.rackspacecloud.com\/",
+                        "versionId":"2"
+                    },
+                    {
+                        "region":"DFW",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v2\/888888",
+                        "versionInfo":"https:\/\/dfw.servers.api.rackspacecloud.com\/v2",
+                        "versionList":"https:\/\/dfw.servers.api.rackspacecloud.com\/",
+                        "versionId":"2"
+                    },
+                    {
+                        "region":"ORD",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v2\/888888",
+                        "versionInfo":"https:\/\/ord.servers.api.rackspacecloud.com\/v2",
+                        "versionList":"https:\/\/ord.servers.api.rackspacecloud.com\/",
+                        "versionId":"2"
+                    }
+                ],
+                "type":"compute"
+            },
+            {
+                "name":"autoscale",
+                "endpoints":[
+                    {
+                        "region":"ORD",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888",
+                        "versionInfo":null,
+                        "versionList":null,
+                        "versionId":"1.0"
+                    },
+                    {
+                        "region":"DFW",
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888",
+                        "versionInfo":null,
+                        "versionList":null,
+                        "versionId":"1.0"
+                    }
+                ],
+                "type":"rax:autoscale"
+            },
+            {
+                "name":"cloudMonitoring",
+                "endpoints":[
+                    {
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888"
+                    }
+                ],
+                "type":"rax:monitor"
+            },
+            {
+                "name":"cloudBackup",
+                "endpoints":[
+                    {
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888"
+                    }
+                ],
+                "type":"rax:backup"
+            },
+            {
+                "name":"cloudServers",
+                "endpoints":[
+                    {
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888",
+                        "versionInfo":"https:\/\/servers.api.rackspacecloud.com\/v1.0",
+                        "versionList":"https:\/\/servers.api.rackspacecloud.com\/",
+                        "versionId":"1.0"
+                    }
+                ],
+                "type":"compute"
+            },
+            {
+                "name":"cloudDNS",
+                "endpoints":[
+                    {
+                        "tenantId":"888888",
+                        "publicURL":"URL/v1.0\/888888"
+                    }
+                ],
+                "type":"rax:dns"
+            }
+        ],
+        "user":{
+            "id":"335853",
+            "roles":[
+                {
+                    "id":"10000150",
+                    "description":"Checkmate Access role",
+                    "name":"checkmate"
+                },
+                {
+                    "tenantId":"MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9",
+                    "id":"5",
+                    "description":"A Role that allows a user access to keystone Service methods",
+                    "name":"object-store:default"
+                },
+                {
+                    "tenantId":"888888",
+                    "id":"6",
+                    "description":"A Role that allows a user access to keystone Service methods",
+                    "name":"compute:default"
+                },
+                {
+                    "id":"3",
+                    "description":"User Admin Role.",
+                    "name":"identity:user-admin"
+                }
+            ],
+            "name":"test",
+            "RAX-AUTH:defaultRegion":"ORD"
+        }
+    }
+}