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/03/03 22:38:43 UTC

[1/5] JCLOUDS-423 - Adds support for Rackspace Cloud Files API - Added support for CloudFilesApi/CDNApi - Added mock/live tests - Refactored listFirstPage() and listAt() API methods to list() and listWithOptions(…) - General Swift API cleanup: docs and t

Repository: jclouds-labs-openstack
Updated Branches:
  refs/heads/master b84b0898c -> 43aa5b3a0


http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesServiceIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesServiceIntegrationLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesServiceIntegrationLiveTest.java
new file mode 100644
index 0000000..66b4b64
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesServiceIntegrationLiveTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.rackspace.cloudfiles.v1.blobstore.integration;
+
+import static org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes.API_KEY_CREDENTIALS;
+
+import java.util.Properties;
+
+import org.jclouds.openstack.swift.v1.blobstore.integration.SwiftServiceIntegrationLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesServiceIntegrationLiveTest")
+public class CloudFilesServiceIntegrationLiveTest extends SwiftServiceIntegrationLiveTest {
+
+   public CloudFilesServiceIntegrationLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+
+   @Override
+   protected Properties setupProperties() {
+      Properties props = super.setupProperties();
+      setIfTestSystemPropertyPresent(props, API_KEY_CREDENTIALS);
+      return props;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesAccountApiLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesAccountApiLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesAccountApiLiveTest.java
new file mode 100644
index 0000000..297ae7d
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesAccountApiLiveTest.java
@@ -0,0 +1,38 @@
+/*
+ * 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.rackspace.cloudfiles.v1.features;
+
+import static org.testng.Assert.assertTrue;
+
+import org.jclouds.openstack.swift.v1.domain.Account;
+import org.jclouds.openstack.swift.v1.features.AccountApiLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesAccountApiLiveTest")
+public class CloudFilesAccountApiLiveTest extends AccountApiLiveTest {
+   
+   public CloudFilesAccountApiLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+   
+   public void testUrlKeyExists() throws Exception {
+      for (String regionId : regions) {
+         Account account = api.accountApiInRegion(regionId).get();
+         assertTrue(account.getTemporaryUrlKey().isPresent());
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesBulkApiLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesBulkApiLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesBulkApiLiveTest.java
new file mode 100644
index 0000000..331ab85
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesBulkApiLiveTest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.rackspace.cloudfiles.v1.features;
+
+import org.jclouds.openstack.swift.v1.features.BulkApiLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesBulkApiLiveTest")
+public class CloudFilesBulkApiLiveTest extends BulkApiLiveTest {
+
+   public CloudFilesBulkApiLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiLiveTest.java
new file mode 100644
index 0000000..fe299ba
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiLiveTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.rackspace.cloudfiles.v1.features;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.jclouds.openstack.swift.v1.options.CreateContainerOptions;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.rackspace.cloudfiles.v1.domain.CDNContainer;
+import org.jclouds.rackspace.cloudfiles.v1.internal.BaseCloudFilesApiLiveTest;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * @author Jeremy Daggett
+ */
+@Test(groups = "live", testName = "CloudFilesCDNApiLiveTest")
+public class CloudFilesCDNApiLiveTest extends BaseCloudFilesApiLiveTest {
+
+   private String name = getClass().getSimpleName();
+
+   public CloudFilesCDNApiLiveTest() {
+      super();
+   }
+   
+   public void testList() throws Exception {
+      for (String regionId : regions) {
+         CDNApi cdnApi = api.cdnApiInRegion(regionId);
+
+         List<CDNContainer> cdnResponse = cdnApi.list().toList();
+         assertNotNull(cdnResponse);
+         for (CDNContainer cdnContainer : cdnResponse) {
+            assertNotNull(cdnContainer.getName());
+            assertTrue(cdnContainer.isEnabled());
+            assertNotNull(cdnContainer.isLogRetentionEnabled());
+            assertNotNull(cdnContainer.getTtl());
+            assertNotNull(cdnContainer.getUri());
+            assertNotNull(cdnContainer.getSslUri());
+            assertNotNull(cdnContainer.getStreamingUri());
+            assertNotNull(cdnContainer.getIosUri());
+         }
+      }
+   }
+
+   public void testListWithOptions() throws Exception {
+      String lexicographicallyBeforeName = name.substring(0, name.length() - 1);
+      for (String regionId : regions) {
+         ListContainerOptions options = ListContainerOptions.Builder.marker(lexicographicallyBeforeName);
+         CDNContainer cdnContainer = api.cdnApiInRegion(regionId).list(options).get(0);
+         
+         assertNotNull(cdnContainer.getName());
+         assertTrue(cdnContainer.isEnabled());
+         assertNotNull(cdnContainer.isLogRetentionEnabled());
+         assertNotNull(cdnContainer.getTtl());
+         assertNotNull(cdnContainer.getUri());
+         assertNotNull(cdnContainer.getSslUri());
+         assertNotNull(cdnContainer.getStreamingUri());
+         assertNotNull(cdnContainer.getIosUri());
+      }
+   }
+
+   public void testGet() throws Exception {
+      for (String regionId : regions) {
+         CDNContainer cdnContainer = api.cdnApiInRegion(regionId).get(name);
+         assertNotNull(cdnContainer);
+      }
+   }
+
+   @BeforeClass(groups = "live")
+   public void setup() {
+      super.setup();
+      for (String regionId : regions) {
+         api.containerApiInRegion(regionId).createIfAbsent(name, CreateContainerOptions.NONE);
+         api.cdnApiInRegion(regionId).enable(name);
+      }
+   }
+
+   @Override
+   @AfterClass(groups = "live")
+   public void tearDown() {
+      for (String regionId : regions) {
+         api.cdnApiInRegion(regionId).disable(name);
+         api.containerApiInRegion(regionId).deleteIfEmpty(name);
+      }
+      super.tearDown();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiMockTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiMockTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiMockTest.java
new file mode 100644
index 0000000..916496e
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesCDNApiMockTest.java
@@ -0,0 +1,381 @@
+/*
+ * 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.rackspace.cloudfiles.v1.features;
+
+import static com.google.common.base.Charsets.US_ASCII;
+import static javax.ws.rs.core.HttpHeaders.CONTENT_LENGTH;
+import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
+import static javax.ws.rs.core.HttpHeaders.ETAG;
+import static javax.ws.rs.core.HttpHeaders.LAST_MODIFIED;
+import static org.jclouds.rackspace.cloudfiles.v1.options.UpdateCDNContainerOptions.Builder.enabled;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_ENABLED;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_IOS_URI;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_LOG_RETENTION;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_SSL_URI;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_STREAMING_URI;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_TTL;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_URI;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.List;
+
+import org.jclouds.io.Payload;
+import org.jclouds.io.Payloads;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
+import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApi;
+import org.jclouds.rackspace.cloudfiles.v1.domain.CDNContainer;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+
+@Test(groups = "unit", testName = "CloudFilesCDNApiMockTest")
+public class CloudFilesCDNApiMockTest extends BaseOpenStackMockTest<CloudFilesApi> {
+
+   List<String> emails = ImmutableList.of("foo@bar.com", "bar@foo.com");
+
+   public void testList() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/cdn_container_list.json"))));
+
+      try {
+         CloudFilesApi api = api(server.getUrl("/").toString(), "rackspace-cloudfiles");
+         CDNApi cdnApi = api.cdnApiInRegion("DFW");
+
+         ImmutableList<CDNContainer> cdnContainers = cdnApi.list().toList();
+
+         assertEquals(cdnContainers, mockContainers);
+
+         assertEquals(server.getRequestCount(), 2);
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/?format=json&enabled_only=true");
+      } finally {
+         server.shutdown();
+      }
+   }
+
+   public void testListWithOptions() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/cdn_container_list_at.json"))));
+
+      try {
+         CloudFilesApi api = api(server.getUrl("/").toString(), "rackspace-cloudfiles");
+         ListContainerOptions options = ListContainerOptions.Builder.marker("cdn-container-3");
+         ImmutableList<CDNContainer> containers = api.cdnApiInRegion("DFW").list(options).toList();
+         
+         for(CDNContainer container : containers) {
+            checkCDNContainer(container);
+         }
+         
+         assertEquals(containers, mockContainers.subList(2, mockContainers.size()));
+
+         assertEquals(server.getRequestCount(), 2);
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/?format=json&enabled_only=true&marker=cdn-container-3");
+      } finally {
+         server.shutdown();
+      }
+   }
+
+   public void testEnableAndDisable() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(enabledResponse().setResponseCode(201)));
+      server.enqueue(addCommonHeaders(enabledResponse().setResponseCode(201)));
+      server.enqueue(addCommonHeaders(disabledResponse().setResponseCode(201)));
+      
+      try {
+         CloudFilesApi api = api(server.getUrl("/").toString(), "rackspace-cloudfiles");
+         CDNApi cdnApi = api.cdnApiInRegion("DFW");
+         
+         // enable a CDN Container
+         URI enabledContainer = cdnApi.enable("container-1");
+         assertNotNull(enabledContainer);
+         
+         // ensure that it is disabled
+         assertTrue(cdnApi.disable("container-1"));
+         
+         // get the container from the CDN and  ensure that it is disabled
+         CDNContainer disabledContainer = cdnApi.get("container-1");
+         checkCDNContainer(disabledContainer);
+         assertFalse(disabledContainer.isEnabled());
+         
+         assertEquals(server.getRequestCount(), 4);
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container-1");
+         assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container-1");
+         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container-1");
+      } finally {
+         server.shutdown();
+      }
+   }
+
+   public void testEnableWithTTL() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(enabledResponse().setResponseCode(201)));
+      
+      try {
+         CloudFilesApi api = api(server.getUrl("/").toString(), "rackspace-cloudfiles");
+         CDNApi cdnApi = api.cdnApiInRegion("DFW");
+         
+         // enable a CDN Container with a TTL
+         URI enabledContainer = cdnApi.enable("container-1", 777777);
+         assertNotNull(enabledContainer);
+
+         assertEquals(server.getRequestCount(), 2);
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container-1");
+      } finally {
+         server.shutdown();
+      }
+   }
+
+   public void testGet() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(enabledResponse().setResponseCode(201)));
+      
+      try {
+         CloudFilesApi api = api(server.getUrl("/").toString(), "rackspace-cloudfiles");
+         CDNApi cdnApi = api.cdnApiInRegion("DFW");
+
+         CDNContainer cdnContainer = cdnApi.get("container-1");
+         checkCDNContainer(cdnContainer);
+         assertEquals(mockCDNContainer, cdnContainer);
+
+         assertEquals(server.getRequestCount(), 2);
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container-1");
+      } finally {
+         server.shutdown();
+      }
+   }
+   
+   public void testGetFail() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
+      
+      try {
+         CloudFilesApi api = api(server.getUrl("/").toString(), "rackspace-cloudfiles");
+         CDNApi cdnApi = api.cdnApiInRegion("DFW");
+
+         CDNContainer cdnContainer = cdnApi.get("container-1");
+
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container-1");
+         assertNull(cdnContainer);
+      } finally {
+         server.shutdown();
+      }
+   }
+
+   public void testPurgeObject() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
+      server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
+      
+      try {
+         CloudFilesApi api = api(server.getUrl("/").toString(), "rackspace-cloudfiles");
+         CDNApi cdnApi = api.cdnApiInRegion("DFW");
+         
+         // purge the object
+         assertTrue(cdnApi.purgeObject("myContainer", "myObject", emails));
+         
+         assertEquals(server.getRequestCount(), 2);
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "DELETE", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject");
+      } finally {
+         server.shutdown();
+      }
+   }
+
+   public void testUpdate() throws Exception {
+      MockWebServer server = mockOpenStackServer();
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json")).setResponseCode(200))); //POST
+      server.enqueue(addCommonHeaders(enabledResponse().setResponseCode(200)));
+      server.enqueue(addCommonHeaders(updatedResponse().setResponseCode(204)));
+      server.enqueue(addCommonHeaders(updatedResponse().setResponseCode(200)));
+      
+      try {
+         CloudFilesApi api = api(server.getUrl("/").toString(), "rackspace-cloudfiles");
+         CDNApi cdnApi = api.cdnApiInRegion("DFW"); 
+         
+         CDNContainer cdnContainer = cdnApi.get("container-1");
+         checkCDNContainer(cdnContainer);
+         
+         // update the CDN Container
+         assertTrue(cdnApi.update("container-1", enabled(false).logRetention(true).ttl(7654321)));
+         
+         cdnContainer = cdnApi.get("container-1");
+         checkCDNContainer(cdnContainer);
+         
+         CDNContainer updatedContainer = CDNContainer.builder()
+               .name("container-1")
+               .enabled(false)
+               .logRetention(true)
+               .ttl(7654321)
+               .uri(URI.create("http://id-1.cdn.rackspace.com"))
+               .sslUri(URI.create("https://ssl-id-1.ssl.rackspace.com"))
+               .streamingUri(URI.create("http://streaming-id-1.stream.rackspace.com"))
+               .iosUri(URI.create("http://ios-id-1.iosr.rackspace.com"))
+               .build();
+         
+         assertEquals(updatedContainer, cdnContainer);
+         
+         assertEquals(server.getRequestCount(), 4);
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container-1");
+         assertRequest(server.takeRequest(), "POST", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container-1");
+         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/container-1");
+      } finally {
+         server.shutdown();
+      }
+   }
+
+   private static final void checkCDNContainer(CDNContainer cdnContainer) {
+      assertNotNull(cdnContainer.getName());
+      assertNotNull(cdnContainer.isEnabled());
+      assertNotNull(cdnContainer.isLogRetentionEnabled());
+      assertNotNull(cdnContainer.getTtl());
+      assertNotNull(cdnContainer.getUri());
+      assertNotNull(cdnContainer.getSslUri());
+      assertNotNull(cdnContainer.getStreamingUri());
+      assertNotNull(cdnContainer.getIosUri());
+   }
+
+   private static final CDNContainer mockCDNContainer = CDNContainer.builder()
+         .name("container-1")
+         .enabled(true)
+         .logRetention(false)
+         .ttl(777777)
+         .uri(URI.create("http://id-1.cdn.rackspace.com"))
+         .sslUri(URI.create("https://ssl-id-1.ssl.rackspace.com"))
+         .streamingUri(URI.create("http://streaming-id-1.stream.rackspace.com"))
+         .iosUri(URI.create("http://ios-id-1.iosr.rackspace.com"))
+         .build();
+
+   private static MockResponse enabledResponse() {
+      return new MockResponse()
+            .addHeader(CDN_ENABLED, "true")
+            .addHeader(CDN_LOG_RETENTION, "false")
+            .addHeader(CDN_TTL, "777777")
+            .addHeader(CDN_URI,"http://id-1.cdn.rackspace.com")
+            .addHeader(CDN_SSL_URI, "https://ssl-id-1.ssl.rackspace.com")
+            .addHeader(CDN_STREAMING_URI, "http://streaming-id-1.stream.rackspace.com")
+            .addHeader(CDN_IOS_URI, "http://ios-id-1.iosr.rackspace.com")
+            .addHeader(CONTENT_LENGTH, "0")
+            .addHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
+   }
+   
+   private static MockResponse disabledResponse() {
+      return new MockResponse()
+            .addHeader(CDN_ENABLED, "false")
+            .addHeader(CDN_LOG_RETENTION, "false")
+            .addHeader(CDN_TTL, "777777")
+            .addHeader(CDN_URI,"http://id-1.cdn.rackspace.com")
+            .addHeader(CDN_SSL_URI, "https://ssl-id-1.ssl.rackspace.com")
+            .addHeader(CDN_STREAMING_URI, "http://streaming-id-1.stream.rackspace.com")
+            .addHeader(CDN_IOS_URI, "http://ios-id-1.iosr.rackspace.com")
+            .addHeader(CONTENT_LENGTH, "0")
+            .addHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
+   }
+
+   private static MockResponse updatedResponse() {
+      return new MockResponse()
+            .addHeader(CDN_ENABLED, "false")
+            .addHeader(CDN_LOG_RETENTION, "true")
+            .addHeader(CDN_TTL, "7654321")
+            .addHeader(CDN_URI,"http://id-1.cdn.rackspace.com")
+            .addHeader(CDN_SSL_URI, "https://ssl-id-1.ssl.rackspace.com")
+            .addHeader(CDN_STREAMING_URI, "http://streaming-id-1.stream.rackspace.com")
+            .addHeader(CDN_IOS_URI, "http://ios-id-1.iosr.rackspace.com")
+            .addHeader(CONTENT_LENGTH, "0")
+            .addHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
+   }
+
+   private static final ImmutableList<CDNContainer> mockContainers = ImmutableList.of(
+         CDNContainer.builder()
+               .name("cdn-container-1")
+               .enabled(true)
+               .logRetention(false)
+               .ttl(259200)
+               .uri(URI.create("http://id-1.cdn.rackspace.com"))
+               .sslUri(URI.create("https://ssl-id-1.ssl.rackspace.com"))
+               .streamingUri(URI.create("http://streaming-id-1.stream.rackspace.com"))
+               .iosUri(URI.create("http://ios-id-1.iosr.rackspace.com"))
+               .build(),
+         CDNContainer.builder()
+               .name("cdn-container-2")
+               .enabled(true)
+               .logRetention(true)
+               .ttl(259200)
+               .uri(URI.create("http://id-2.cdn.rackspace.com"))
+               .sslUri(URI.create("https://ssl-id-2.ssl.rackspace.com"))
+               .streamingUri(URI.create("http://streaming-id-2.stream.rackspace.com"))
+               .iosUri(URI.create("http://ios-id-2.iosr.rackspace.com"))
+               .build(),
+         CDNContainer.builder()
+               .name("cdn-container-3")
+               .enabled(true)
+               .logRetention(false)
+               .ttl(259200)
+               .uri(URI.create("http://id-3.cdn.rackspace.com"))
+               .sslUri(URI.create("https://ssl-id-3.ssl.rackspace.com"))
+               .streamingUri(URI.create("http://streaming-id-3.stream.rackspace.com"))
+               .iosUri(URI.create("http://ios-id-3.iosr.rackspace.com"))
+               .build(),
+         CDNContainer.builder()
+               .name("cdn-container-4")
+               .enabled(true)
+               .logRetention(true)
+               .ttl(777777)
+               .uri(URI.create("http://id-4.cdn.rackspace.com"))
+               .sslUri(URI.create("https://ssl-id-4.ssl.rackspace.com"))
+               .streamingUri(URI.create("http://streaming-id-4.stream.rackspace.com"))
+               .iosUri(URI.create("http://ios-id-4.iosr.rackspace.com"))
+               .build());
+
+   private static MockResponse objectResponse() {
+      return new MockResponse()
+            .addHeader(LAST_MODIFIED, "Fri, 12 Jun 2010 13:40:18 GMT")
+            .addHeader(ETAG, "8a964ee2a5e88be344f36c22562a6486")
+            // TODO: MWS doesn't allow you to return content length w/o content
+            // on HEAD!
+            .setBody("ABCD".getBytes(US_ASCII))
+            .addHeader(CONTENT_LENGTH, "4").addHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
+   }
+
+   private static final byte[] NO_CONTENT = new byte[] {};
+   
+   private static Payload payload(long bytes, String contentType) {
+      Payload payload = Payloads.newByteArrayPayload(NO_CONTENT);
+      payload.getContentMetadata().setContentLength(bytes);
+      payload.getContentMetadata().setContentType(contentType);
+      return payload;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesContainerApiLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesContainerApiLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesContainerApiLiveTest.java
new file mode 100644
index 0000000..4db4e5a
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesContainerApiLiveTest.java
@@ -0,0 +1,27 @@
+/*
+ * 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.rackspace.cloudfiles.v1.features;
+
+import org.jclouds.openstack.swift.v1.features.ContainerApiLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesContainerApiLiveTest")
+public class CloudFilesContainerApiLiveTest extends ContainerApiLiveTest {
+   public CloudFilesContainerApiLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesObjectApiLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesObjectApiLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesObjectApiLiveTest.java
new file mode 100644
index 0000000..a0ffa31
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/features/CloudFilesObjectApiLiveTest.java
@@ -0,0 +1,27 @@
+/*
+ * 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.rackspace.cloudfiles.v1.features;
+
+import org.jclouds.openstack.swift.v1.features.ObjectApiLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesObjectApiLiveTest")
+public class CloudFilesObjectApiLiveTest extends ObjectApiLiveTest {
+   public CloudFilesObjectApiLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/internal/BaseCloudFilesApiLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/internal/BaseCloudFilesApiLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/internal/BaseCloudFilesApiLiveTest.java
new file mode 100644
index 0000000..6586cd1
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/internal/BaseCloudFilesApiLiveTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.rackspace.cloudfiles.v1.internal;
+
+import static org.testng.Assert.assertNotNull;
+
+import org.jclouds.openstack.swift.v1.domain.Container;
+import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
+import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApi;
+import org.testng.annotations.Test;
+
+/**
+ * Base class for all Cloud Files API Live tests.
+ * 
+ * @author Jeremy Daggett
+ */
+@Test(groups = "live", testName = "BaseCloudFilesApiLiveTest")
+public abstract class BaseCloudFilesApiLiveTest extends BaseSwiftApiLiveTest<CloudFilesApi> {
+   
+   protected BaseCloudFilesApiLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/resources/cdn_container_list.json
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/resources/cdn_container_list.json b/rackspace-cloudfiles/src/test/resources/cdn_container_list.json
new file mode 100644
index 0000000..4dce8db
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/resources/cdn_container_list.json
@@ -0,0 +1,42 @@
+[
+    {
+        "cdn_streaming_uri": "http://streaming-id-1.stream.rackspace.com",
+        "name": "cdn-container-1",
+        "cdn_ios_uri": "http://ios-id-1.iosr.rackspace.com",
+        "cdn_ssl_uri": "https://ssl-id-1.ssl.rackspace.com",
+        "cdn_enabled": true,
+        "ttl": 259200,
+        "log_retention": false,
+        "cdn_uri": "http://id-1.cdn.rackspace.com"
+    },
+    {
+        "cdn_streaming_uri": "http://streaming-id-2.stream.rackspace.com",
+        "name": "cdn-container-2",
+        "cdn_ios_uri": "http://ios-id-2.iosr.rackspace.com",
+        "cdn_ssl_uri": "https://ssl-id-2.ssl.rackspace.com",
+        "cdn_enabled": true,
+        "ttl": 259200,
+        "log_retention": true,
+        "cdn_uri": "http://id-2.cdn.rackspace.com"
+    },
+    {
+        "cdn_streaming_uri": "http://streaming-id-3.stream.rackspace.com",
+        "name": "cdn-container-3",
+        "cdn_ios_uri": "http://ios-id-3.iosr.rackspace.com",
+        "cdn_ssl_uri": "https://ssl-id-3.ssl.rackspace.com",
+        "cdn_enabled": true,
+        "ttl": 259200,
+        "log_retention": false,
+        "cdn_uri": "http://id-3.cdn.rackspace.com"
+    },
+    {
+        "cdn_streaming_uri": "http://streaming-id-4.stream.rackspace.com",
+        "name": "cdn-container-4",
+        "cdn_ios_uri": "http://ios-id-4.iosr.rackspace.com",
+        "cdn_ssl_uri": "https://ssl-id-4.ssl.rackspace.com",
+        "cdn_enabled": true,
+        "ttl": 777777,
+        "log_retention": true,
+        "cdn_uri": "http://id-4.cdn.rackspace.com"
+    }
+]

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/resources/cdn_container_list_at.json
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/resources/cdn_container_list_at.json b/rackspace-cloudfiles/src/test/resources/cdn_container_list_at.json
new file mode 100644
index 0000000..f1fa9ee
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/resources/cdn_container_list_at.json
@@ -0,0 +1,22 @@
+[
+    {
+        "cdn_streaming_uri": "http://streaming-id-3.stream.rackspace.com",
+        "name": "cdn-container-3",
+        "cdn_ios_uri": "http://ios-id-3.iosr.rackspace.com",
+        "cdn_ssl_uri": "https://ssl-id-3.ssl.rackspace.com",
+        "cdn_enabled": true,
+        "ttl": 259200,
+        "log_retention": false,
+        "cdn_uri": "http://id-3.cdn.rackspace.com"
+    },
+    {
+        "cdn_streaming_uri": "http://streaming-id-4.stream.rackspace.com",
+        "name": "cdn-container-4",
+        "cdn_ios_uri": "http://ios-id-4.iosr.rackspace.com",
+        "cdn_ssl_uri": "https://ssl-id-4.ssl.rackspace.com",
+        "cdn_enabled": true,
+        "ttl": 777777,
+        "log_retention": true,
+        "cdn_uri": "http://id-4.cdn.rackspace.com"
+    }
+]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/resources/logback.xml
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/resources/logback.xml b/rackspace-cloudfiles/src/test/resources/logback.xml
new file mode 100644
index 0000000..ce891f1
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/resources/logback.xml
@@ -0,0 +1,71 @@
+<?xml version="1.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.
+
+-->
+<configuration scan="false">
+    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+        <file>target/test-data/jclouds.log</file>
+
+        <encoder>
+            <Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
+        </encoder>
+    </appender>
+
+    <appender name="WIREFILE" class="ch.qos.logback.core.FileAppender">
+        <file>target/test-data/jclouds-wire.log</file>
+
+        <encoder>
+            <Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
+        </encoder>
+    </appender>
+
+    <appender name="BLOBSTOREFILE" class="ch.qos.logback.core.FileAppender">
+        <file>target/test-data/jclouds-blobstore.log</file>
+
+        <encoder>
+            <Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
+        </encoder>
+    </appender>
+    
+    <root>
+        <level value="warn" />
+    </root>
+
+    <logger name="org.jclouds">
+        <level value="DEBUG" />
+        <appender-ref ref="FILE" />
+    </logger>
+
+<!--
+    <logger name="jclouds.wire">
+        <level value="DEBUG" />
+        <appender-ref ref="WIREFILE" />
+    </logger>
+-->
+
+    <logger name="jclouds.headers">
+        <level value="DEBUG" />
+        <appender-ref ref="WIREFILE" />
+    </logger>
+
+    <logger name="jclouds.blobstore">
+        <level value="DEBUG" />
+        <appender-ref ref="BLOBSTOREFILE" />
+    </logger>
+
+</configuration>


[5/5] git commit: JCLOUDS-423 - Adds support for Rackspace Cloud Files API - Added support for CloudFilesApi/CDNApi - Added mock/live tests - Refactored listFirstPage() and listAt() API methods to list() and listWithOptions(…) - General Swift API cleanup

Posted by za...@apache.org.
JCLOUDS-423 - Adds support for Rackspace Cloud Files API - Added support for CloudFilesApi/CDNApi - Added mock/live tests - Refactored listFirstPage() and listAt() API methods to list() and listWithOptions(…) - General Swift API cleanup: docs and tests - Added support for Internal URL - Updated JavaDocs and domain objects. - Added support for Cloud Files US


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/43aa5b3a
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/tree/43aa5b3a
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/diff/43aa5b3a

Branch: refs/heads/master
Commit: 43aa5b3a00c12a741898e885be78bb8bdfb31ce2
Parents: b84b089
Author: Jeremy Daggett <je...@rackspace.com>
Authored: Fri Feb 14 09:36:53 2014 -0800
Committer: Zack Shoylev <za...@rackspace.com>
Committed: Mon Mar 3 15:32:58 2014 -0600

----------------------------------------------------------------------
 .../openstack/swift/v1/CopyObjectException.java |   4 +-
 .../jclouds/openstack/swift/v1/SwiftApi.java    |   9 +-
 .../openstack/swift/v1/SwiftApiMetadata.java    |   9 +-
 .../openstack/swift/v1/TemporaryUrlSigner.java  |   8 +-
 .../swift/v1/binders/BindMetadataToHeaders.java |  19 +-
 .../blobstore/RegionScopedSwiftBlobStore.java   |  14 +-
 .../v1/blobstore/functions/ToBlobMetadata.java  |  20 +-
 .../blobstore/functions/ToResourceMetadata.java |   4 +-
 .../swift/v1/config/BaseSwiftHttpApiModule.java |  46 +++
 .../swift/v1/config/SwiftHttpApiModule.java     |  19 +-
 .../swift/v1/config/SwiftTypeAdapters.java      |   4 +-
 .../openstack/swift/v1/domain/Account.java      |  82 ++--
 .../swift/v1/domain/BulkDeleteResponse.java     |  45 ++-
 .../openstack/swift/v1/domain/Container.java    |  89 +++--
 .../swift/v1/domain/ExtractArchiveResponse.java |  35 +-
 .../openstack/swift/v1/domain/ObjectList.java   |  16 +-
 .../openstack/swift/v1/domain/Segment.java      |  48 +--
 .../openstack/swift/v1/domain/SwiftObject.java  | 105 ++---
 .../openstack/swift/v1/features/AccountApi.java |  63 ++-
 .../openstack/swift/v1/features/BulkApi.java    |  23 +-
 .../swift/v1/features/ContainerApi.java         |  95 ++---
 .../openstack/swift/v1/features/ObjectApi.java  | 102 ++---
 .../swift/v1/features/StaticLargeObjectApi.java |  20 +-
 .../v1/functions/EntriesWithoutMetaPrefix.java  |   4 +-
 .../v1/functions/ParseAccountFromHeaders.java   |  12 +-
 .../v1/functions/ParseContainerFromHeaders.java |  17 +-
 .../v1/functions/ParseObjectFromResponse.java   |  12 +-
 .../functions/ParseObjectListFromResponse.java  |  10 +-
 .../swift/v1/handlers/SwiftErrorHandler.java    |   4 +
 .../v1/options/CreateContainerOptions.java      |  49 ++-
 .../swift/v1/options/ListContainerOptions.java  |  55 ++-
 .../swift/v1/reference/SwiftHeaders.java        |  54 ++-
 .../swift/v1/TemporaryUrlSignerLiveTest.java    |  10 +-
 .../swift/v1/TemporaryUrlSignerMockTest.java    |   5 +-
 .../SwiftBlobIntegrationLiveTest.java           |   3 +-
 .../integration/SwiftBlobLiveTest.java          |   3 +-
 .../integration/SwiftBlobSignerLiveTest.java    |   3 +-
 .../SwiftContainerIntegrationLiveTest.java      |   3 +-
 .../integration/SwiftContainerLiveTest.java     |   3 +-
 .../SwiftServiceIntegrationLiveTest.java        |   3 +-
 .../swift/v1/config/SwiftTypeAdaptersTest.java  |  66 ++--
 .../swift/v1/features/AccountApiLiveTest.java   |  19 +-
 .../swift/v1/features/AccountApiMockTest.java   |  59 +--
 .../swift/v1/features/BulkApiLiveTest.java      |  35 +-
 .../swift/v1/features/BulkApiMockTest.java      |  14 +-
 .../swift/v1/features/ContainerApiLiveTest.java |  63 +--
 .../swift/v1/features/ContainerApiMockTest.java | 146 +++----
 .../features/CreatePublicContainerLiveTest.java |   7 +-
 .../swift/v1/features/ObjectApiLiveTest.java    | 135 ++++---
 .../swift/v1/features/ObjectApiMockTest.java    | 168 ++++----
 .../features/StaticLargeObjectApiLiveTest.java  |  34 +-
 .../features/StaticLargeObjectApiMockTest.java  |  30 +-
 .../features/UrlEncodeAndJoinOnNewlineTest.java |   5 +-
 .../swift/v1/internal/BaseSwiftApiLiveTest.java |  18 +-
 .../src/test/resources/container_list.json      |  12 +
 .../src/test/resources/object_list.json         |  16 +
 pom.xml                                         |   2 +
 rackspace-cloudfiles-us/README.md               |  20 +
 rackspace-cloudfiles-us/pom.xml                 | 176 +++++++++
 .../us/CloudFilesUSProviderMetadata.java        | 145 +++++++
 .../org.jclouds.providers.ProviderMetadata      |  18 +
 .../cloudfiles/us/CloudFilesUSProviderTest.java |  29 ++
 .../CloudFilesUSBlobIntegrationLiveTest.java    |  27 ++
 .../integration/CloudFilesUSBlobLiveTest.java   |  27 ++
 .../CloudFilesUSBlobSignerLiveTest.java         |  27 ++
 ...loudFilesUSContainerIntegrationLiveTest.java |  27 ++
 .../CloudFilesUSContainerLiveTest.java          |  27 ++
 .../CloudFilesUSServiceIntegrationLiveTest.java |  36 ++
 .../src/test/resources/logback.xml              |  71 ++++
 rackspace-cloudfiles/README.md                  |  20 +
 rackspace-cloudfiles/pom.xml                    | 171 +++++++++
 .../rackspace/cloudfiles/v1/CloudFilesApi.java  |  50 +++
 .../cloudfiles/v1/CloudFilesApiMetadata.java    | 104 +++++
 .../BindCDNPurgeEmailAddressesToHeaders.java    |  56 +++
 .../v1/config/CloudFilesHttpApiModule.java      |  50 +++
 .../cloudfiles/v1/domain/CDNContainer.java      | 264 +++++++++++++
 .../cloudfiles/v1/features/CDNApi.java          | 205 ++++++++++
 .../functions/ParseCDNContainerFromHeaders.java |  84 ++++
 .../ParseCDNContainerURIFromHeaders.java        |  45 +++
 .../v1/functions/RegionToCDNEndpoint.java       |  77 ++++
 .../v1/handlers/CloudFilesErrorHandler.java     |  91 +++++
 .../v1/options/UpdateCDNContainerOptions.java   | 163 ++++++++
 .../v1/reference/CloudFilesHeaders.java         |  58 +++
 .../services/org.jclouds.apis.ApiMetadata       |  18 +
 .../cloudfiles/v1/CloudFilesApiLiveTest.java    |  30 ++
 .../v1/CloudFilesApiMetadataTest.java           |  35 ++
 ...CDNPurgeEmailAddressesToHeadersMockTest.java |  77 ++++
 ...lesRegionScopedBlobStoreContextLiveTest.java |  39 ++
 .../CloudFilesBlobIntegrationLiveTest.java      |  39 ++
 .../integration/CloudFilesBlobLiveTest.java     |  39 ++
 .../CloudFilesBlobSignerLiveTest.java           |  39 ++
 .../CloudFilesContainerIntegrationLiveTest.java |  39 ++
 .../CloudFilesContainerLiveTest.java            |  56 +++
 .../CloudFilesServiceIntegrationLiveTest.java   |  39 ++
 .../features/CloudFilesAccountApiLiveTest.java  |  38 ++
 .../v1/features/CloudFilesBulkApiLiveTest.java  |  28 ++
 .../v1/features/CloudFilesCDNApiLiveTest.java   | 105 +++++
 .../v1/features/CloudFilesCDNApiMockTest.java   | 381 +++++++++++++++++++
 .../CloudFilesContainerApiLiveTest.java         |  27 ++
 .../features/CloudFilesObjectApiLiveTest.java   |  27 ++
 .../v1/internal/BaseCloudFilesApiLiveTest.java  |  37 ++
 .../src/test/resources/cdn_container_list.json  |  42 ++
 .../test/resources/cdn_container_list_at.json   |  22 ++
 .../src/test/resources/logback.xml              |  71 ++++
 104 files changed, 4374 insertions(+), 880 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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
index 9258662..a958b66 100644
--- 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
@@ -22,11 +22,11 @@ import org.jclouds.rest.ResourceNotFoundException;
 
 /**
  * Thrown when an object cannot be copied.
- *
- * @see {@link SwiftErrorHandler#handleError(HttpCommand, HttpResponse)}
  *  
  * @author Everett Toews
  * @author Jeremy Daggett
+ * 
+ * @see {@link SwiftErrorHandler#handleError(HttpCommand, HttpResponse)}
  */
 public class CopyObjectException extends ResourceNotFoundException {
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApi.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApi.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApi.java
index 57ebc9c..3e48b2c 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApi.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApi.java
@@ -36,10 +36,13 @@ import org.jclouds.rest.annotations.EndpointParam;
 import com.google.inject.Provides;
 
 /**
- * @see <a
- *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content">api
- *      doc</a>
+ * Provides access to the OpenStack Object Storage (Swift) API.
+ * <p/>
+ * OpenStack Object Storage is an object-based storage system that stores content and metadata
+ * as objects. You create, modify, and get objects and metadata using this API.
+ * 
  * @author Adrian Cole
+ * @author Jeremy Daggett
  * @author Zack Shoylev
  */
 public interface SwiftApi extends Closeable {

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
index 7b25ae3..b7957ce 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
@@ -23,6 +23,7 @@ import static org.jclouds.reflect.Reflection2.typeToken;
 import java.net.URI;
 import java.util.Properties;
 
+import org.jclouds.apis.ApiMetadata;
 import org.jclouds.openstack.keystone.v2_0.config.AuthenticationApiModule;
 import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
 import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
@@ -33,16 +34,18 @@ import org.jclouds.openstack.swift.v1.blobstore.config.SwiftBlobStoreContextModu
 import org.jclouds.openstack.swift.v1.config.SwiftHttpApiModule;
 import org.jclouds.openstack.swift.v1.config.SwiftTypeAdapters;
 import org.jclouds.openstack.v2_0.ServiceType;
+import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.rest.internal.BaseHttpApiMetadata;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Module;
 
 /**
- * Implementation of {@link ApiMetadata} for Swift 1.0 API
+ * Implementation of {@link ApiMetadata} for the Swift API.
  * 
  * @author Adrian Cole
  * @author Zack Shoylev
+ * @author Jeremy Daggett
  */
 public class SwiftApiMetadata extends BaseHttpApiMetadata<SwiftApi> {
    
@@ -74,8 +77,8 @@ public class SwiftApiMetadata extends BaseHttpApiMetadata<SwiftApi> {
          .identityName("${tenantName}:${userName} or ${userName}, if your keystone supports a default tenant")
          .credentialName("${password}")
          .documentation(URI.create("http://docs.openstack.org/api/openstack-object-storage/1.0/content/ch_object-storage-dev-overview.html"))
-         .version("1.0")
-         .endpointName("KeyStone base url ending in /v2.0/")
+         .version("1")
+         .endpointName("Keystone base url ending in /v2.0/")
          .defaultEndpoint("http://localhost:5000/v2.0/")
          .defaultProperties(SwiftApiMetadata.defaultProperties())
          .view(typeToken(RegionScopedBlobStoreContext.class))

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java
index 7a3cf8b..c6d6030 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java
@@ -35,10 +35,6 @@ import com.google.common.base.Supplier;
 
 /**
  * Use this utility to create temporary urls.
- * 
- * @see <a
- *      href="http://docs.openstack.org/trunk/config-reference/content/object-storage-tempurl.html">Temporary
- *      URL Documentation</a>
  */
 public class TemporaryUrlSigner {
 
@@ -82,12 +78,12 @@ public class TemporaryUrlSigner {
 
       @Override
       public String get() {
-         return api.get().temporaryUrlKey().orNull();
+         return api.get().getTemporaryUrlKey().orNull();
       }
 
       @Override
       public String toString() {
-         return format("get().temporaryUrlKey() using %s", api);
+         return format("get().getTemporaryUrlKey() using %s", api);
       }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java
index 8af9f9f..4dabc68 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java
@@ -16,6 +16,10 @@
  */
 package org.jclouds.openstack.swift.v1.binders;
 
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_METADATA_PREFIX;
+
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -48,45 +52,42 @@ import com.google.common.collect.ImmutableMultimap.Builder;
  * HTTP response headers keys are known to be case-insensitive, but this
  * practice of mixing up case will prevent metadata keys such as those in
  * Turkish from working.
- * 
- * @see <a
- *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/create-update-account-metadata.html">documentation</a>
  */
 public class BindMetadataToHeaders implements Binder {
 
    public static class BindAccountMetadataToHeaders extends BindMetadataToHeaders {
       BindAccountMetadataToHeaders() {
-         super("x-account-meta-");
+         super(ACCOUNT_METADATA_PREFIX);
       }
    }
 
    public static class BindRemoveAccountMetadataToHeaders extends BindMetadataToHeaders.ForRemoval {
       BindRemoveAccountMetadataToHeaders() {
-         super("x-account-meta-");
+         super(ACCOUNT_METADATA_PREFIX);
       }
    }
 
    public static class BindContainerMetadataToHeaders extends BindMetadataToHeaders {
       BindContainerMetadataToHeaders() {
-         super("x-container-meta-");
+         super(CONTAINER_METADATA_PREFIX);
       }
    }
 
    public static class BindRemoveContainerMetadataToHeaders extends BindMetadataToHeaders.ForRemoval {
       BindRemoveContainerMetadataToHeaders() {
-         super("x-container-meta-");
+         super(CONTAINER_METADATA_PREFIX);
       }
    }
 
    public static class BindObjectMetadataToHeaders extends BindMetadataToHeaders {
       BindObjectMetadataToHeaders() {
-         super("x-object-meta-");
+         super(OBJECT_METADATA_PREFIX);
       }
    }
 
    public static class BindRemoveObjectMetadataToHeaders extends BindMetadataToHeaders.ForRemoval {
       BindRemoveObjectMetadataToHeaders() {
-         super("x-object-meta-");
+         super(OBJECT_METADATA_PREFIX);
       }
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
index 5aa926f..480034a 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
@@ -110,7 +110,7 @@ public class RegionScopedSwiftBlobStore implements BlobStore {
    @Override
    public PageSet<? extends StorageMetadata> list() {
       // TODO: there may eventually be >10k containers..
-      FluentIterable<StorageMetadata> containers = api.containerApiInRegion(region.getId()).listFirstPage()
+      FluentIterable<StorageMetadata> containers = api.containerApiInRegion(region.getId()).list()
             .transform(toResourceMetadata);
       return new PageSetImpl<StorageMetadata>(containers, null);
    }
@@ -153,7 +153,7 @@ public class RegionScopedSwiftBlobStore implements BlobStore {
          containerCache.put(container, Optional.<Container> absent());
          return new PageSetImpl<StorageMetadata>(ImmutableList.<StorageMetadata> of(), null);
       } else {
-         containerCache.put(container, Optional.of(objects.container()));
+         containerCache.put(container, Optional.of(objects.getContainer()));
          List<? extends StorageMetadata> list = transform(objects, toBlobMetadata(container));
          int limit = Optional.fromNullable(options.getMaxResults()).or(10000);
          String marker = list.size() == limit ? list.get(limit - 1).getName() : null;
@@ -214,8 +214,8 @@ public class RegionScopedSwiftBlobStore implements BlobStore {
          return null;
       }
       Blob blob = new BlobImpl(toBlobMetadata(container).apply(object));
-      blob.setPayload(object.payload());
-      blob.setAllHeaders(object.headers());
+      blob.setPayload(object.getPayload());
+      blob.setAllHeaders(object.getHeaders());
       return blob;
    }
 
@@ -236,13 +236,13 @@ public class RegionScopedSwiftBlobStore implements BlobStore {
 
    @Override
    public boolean directoryExists(String containerName, String directory) {
-      return api.objectApiInRegionForContainer(region.getId(), containerName) //
+      return api.objectApiInRegionForContainer(region.getId(), containerName)
             .head(directory) != null;
    }
 
    @Override
    public void createDirectory(String containerName, String directory) {
-      api.objectApiInRegionForContainer(region.getId(), containerName) //
+      api.objectApiInRegionForContainer(region.getId(), containerName)
             .replace(directory, directoryPayload, ImmutableMap.<String, String> of());
    }
 
@@ -261,7 +261,7 @@ public class RegionScopedSwiftBlobStore implements BlobStore {
    public long countBlobs(String containerName) {
       Container container = api.containerApiInRegion(region.getId()).get(containerName);
       // undefined if container doesn't exist, so default to zero
-      return container != null ? container.objectCount() : 0;
+      return container != null ? container.getObjectCount() : 0;
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToBlobMetadata.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToBlobMetadata.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToBlobMetadata.java
index eda42aa..5a0ee17 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToBlobMetadata.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToBlobMetadata.java
@@ -43,17 +43,17 @@ public class ToBlobMetadata implements Function<SwiftObject, MutableBlobMetadata
       if (from == null)
          return null;
       MutableBlobMetadata to = new MutableBlobMetadataImpl();
-      to.setContainer(container.name());
-      if (container.anybodyRead().isPresent()) {
-         to.setPublicUri(from.uri());
+      to.setContainer(container.getName());
+      if (container.getAnybodyRead().isPresent()) {
+         to.setPublicUri(from.getUri());
       }
-      to.setUri(from.uri());
-      to.setETag(from.etag());
-      to.setName(from.name());
-      to.setLastModified(from.lastModified());
-      to.setContentMetadata(from.payload().getContentMetadata());
-      to.getContentMetadata().setContentMD5(base16().lowerCase().decode(from.etag()));
-      to.setUserMetadata(from.metadata());
+      to.setUri(from.getUri());
+      to.setETag(from.getEtag());
+      to.setName(from.getName());
+      to.setLastModified(from.getLastModified());
+      to.setContentMetadata(from.getPayload().getContentMetadata());
+      to.getContentMetadata().setContentMD5(base16().lowerCase().decode(from.getEtag()));
+      to.setUserMetadata(from.getMetadata());
       String directoryName = ifDirectoryReturnName.execute(to);
       if (directoryName != null) {
          to.setName(directoryName);

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToResourceMetadata.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToResourceMetadata.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToResourceMetadata.java
index 0384388..bc5e186 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToResourceMetadata.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToResourceMetadata.java
@@ -35,10 +35,10 @@ public class ToResourceMetadata implements Function<Container, StorageMetadata>
    @Override
    public StorageMetadata apply(Container from) {
       MutableStorageMetadata to = new MutableStorageMetadataImpl();
-      to.setName(from.name());
+      to.setName(from.getName());
       to.setLocation(region);
       to.setType(StorageType.CONTAINER);
-      to.setUserMetadata(from.metadata());
+      to.setUserMetadata(from.getMetadata());
       return to;
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/BaseSwiftHttpApiModule.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/BaseSwiftHttpApiModule.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/BaseSwiftHttpApiModule.java
new file mode 100644
index 0000000..d6d8b6a
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/BaseSwiftHttpApiModule.java
@@ -0,0 +1,46 @@
+/*
+ * 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.config;
+
+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.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.handlers.SwiftErrorHandler;
+import org.jclouds.rest.ConfiguresHttpApi;
+import org.jclouds.rest.config.HttpApiModule;
+
+@ConfiguresHttpApi
+public abstract class BaseSwiftHttpApiModule<A extends SwiftApi> extends HttpApiModule<A> {
+
+   protected BaseSwiftHttpApiModule(Class<A> api) {
+      super(api);
+   }
+
+   @Override
+   protected void configure() {
+      super.configure();
+   }
+
+   @Override
+   protected void bindErrorHandlers() {
+      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(SwiftErrorHandler.class);
+      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(SwiftErrorHandler.class);
+      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(SwiftErrorHandler.class);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftHttpApiModule.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftHttpApiModule.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftHttpApiModule.java
index 37e4b2d..cb93760 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftHttpApiModule.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftHttpApiModule.java
@@ -15,25 +15,18 @@
  * limitations under the License.
  */
 package org.jclouds.openstack.swift.v1.config;
-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.openstack.swift.v1.SwiftApi;
-import org.jclouds.openstack.swift.v1.handlers.SwiftErrorHandler;
 import org.jclouds.rest.ConfiguresHttpApi;
-import org.jclouds.rest.config.HttpApiModule;
 
 @ConfiguresHttpApi
-public class SwiftHttpApiModule extends HttpApiModule<SwiftApi> {
-  
+public class SwiftHttpApiModule extends BaseSwiftHttpApiModule<SwiftApi> {
+
    public SwiftHttpApiModule() {
-   }   
+      super(SwiftApi.class);
+   }
 
    @Override
-   protected void bindErrorHandlers() {
-      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(SwiftErrorHandler.class);
-      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(SwiftErrorHandler.class);
-      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(SwiftErrorHandler.class);
+   protected void configure() {
+      super.configure();
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdapters.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdapters.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdapters.java
index f556142..4eafdb6 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdapters.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdapters.java
@@ -43,8 +43,8 @@ public class SwiftTypeAdapters extends AbstractModule {
 
    @Provides
    public Map<Type, Object> provideCustomAdapterBindings() {
-      return ImmutableMap.<Type, Object> builder() //
-            .put(ExtractArchiveResponse.class, new ExtractArchiveResponseAdapter()) //
+      return ImmutableMap.<Type, Object> builder()
+            .put(ExtractArchiveResponse.class, new ExtractArchiveResponseAdapter())
             .put(BulkDeleteResponse.class, new BulkDeleteResponseAdapter()).build();
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Account.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Account.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Account.java
index a3857f0..c8e760a 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Account.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Account.java
@@ -23,15 +23,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.jclouds.openstack.swift.v1.features.AccountApi;
+
 import com.google.common.base.Objects;
 import com.google.common.base.Objects.ToStringHelper;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
 
 /**
- * @see <a
- *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/retrieve-account-metadata.html">api
- *      doc</a>
+ * Represents an Account in OpenStack Object Storage.
+ * 
+ * @author Jeremy Daggett
+ * 
+ * @see AccountApi
  */
 public class Account {
 
@@ -48,27 +52,42 @@ public class Account {
       this.metadata = checkNotNull(metadata, "metadata");
    }
 
-   public long containerCount() {
+   /**
+    * @return The count of containers for this account.
+    */
+   public long getContainerCount() {
       return containerCount;
    }
 
-   public long objectCount() {
+   /**
+    * @return The count of objects for this account.
+    */
+   public long getObjectCount() {
       return objectCount;
    }
 
-   public long bytesUsed() {
+   /**
+    * @return The number of bytes used by this account.
+    */
+   public long getBytesUsed() {
       return bytesUsed;
    }
 
-   public Optional<String> temporaryUrlKey() {
+   /**
+    * @return The {@link Optional&lt;String&gt;} temporary URL key for this account.
+    */
+   public Optional<String> getTemporaryUrlKey() {
       return Optional.fromNullable(metadata.get("temp-url-key"));
    }
 
    /**
+    * <h3>NOTE</h3>
     * In current swift implementations, headers keys are lower-cased. This means
     * characters such as turkish will probably not work out well.
+    *
+    * @return a {@code Map<String, String>} containing the account metadata.
     */
-   public Map<String, String> metadata() {
+   public Map<String, String> getMetadata() {
       return metadata;
    }
 
@@ -79,10 +98,10 @@ public class Account {
       }
       if (object instanceof Account) {
          Account that = Account.class.cast(object);
-         return equal(containerCount(), that.containerCount()) //
-               && equal(objectCount(), that.objectCount()) //
-               && equal(bytesUsed(), that.bytesUsed()) //
-               && equal(metadata(), that.metadata());
+         return equal(getContainerCount(), that.getContainerCount())
+               && equal(getObjectCount(), that.getObjectCount())
+               && equal(getBytesUsed(), that.getBytesUsed())
+               && equal(getMetadata(), that.getMetadata());
       } else {
          return false;
       }
@@ -90,7 +109,7 @@ public class Account {
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(containerCount(), objectCount(), bytesUsed());
+      return Objects.hashCode(getContainerCount(), getObjectCount(), getBytesUsed(), getMetadata());
    }
 
    @Override
@@ -99,11 +118,11 @@ public class Account {
    }
 
    protected ToStringHelper string() {
-      return toStringHelper("") //
-            .add("containerCount", containerCount()) //
-            .add("objectCount", objectCount()) //
-            .add("bytesUsed", bytesUsed()) //
-            .add("metadata", metadata());
+      return toStringHelper("")
+            .add("containerCount", getContainerCount())
+            .add("objectCount", getObjectCount())
+            .add("bytesUsed", getBytesUsed())
+            .add("metadata", getMetadata());
    }
 
    public static Builder builder() {
@@ -121,7 +140,9 @@ public class Account {
       protected Map<String, String> metadata = ImmutableMap.of();
 
       /**
-       * @see Account#containerCount()
+       * @param containerCount  the count of containers for this account.
+       * 
+       * @see Account#getContainerCount()
        */
       public Builder containerCount(long containerCount) {
          this.containerCount = containerCount;
@@ -129,7 +150,9 @@ public class Account {
       }
 
       /**
-       * @see Account#objectCount()
+       * @param objectCount  the count of objects for this account.
+       * 
+       * @see Account#getObjectCount()
        */
       public Builder objectCount(long objectCount) {
          this.objectCount = objectCount;
@@ -137,7 +160,9 @@ public class Account {
       }
 
       /**
-       * @see Account#bytesUsed()
+       * @param bytesUsed  the number of bytes used by this account.
+       * 
+       * @see Account#getBytesUsed()
        */
       public Builder bytesUsed(long bytesUsed) {
          this.bytesUsed = bytesUsed;
@@ -145,10 +170,13 @@ public class Account {
       }
 
       /**
-       * Will lower-case all metadata keys due to a swift implementation
+       * <h3>NOTE</h3>
+       * This method will lower-case all metadata keys due to a Swift implementation
        * decision.
        * 
-       * @see Account#metadata()
+       * @param metadata  the metadata for this account. 
+       * 
+       * @see Account#getMetadata()
        */
       public Builder metadata(Map<String, String> metadata) {
          ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String> builder();
@@ -164,10 +192,10 @@ public class Account {
       }
 
       public Builder fromContainer(Account from) {
-         return containerCount(from.containerCount())//
-               .objectCount(from.objectCount())//
-               .bytesUsed(from.bytesUsed()) //
-               .metadata(from.metadata());
+         return containerCount(from.getContainerCount())
+               .objectCount(from.getObjectCount())
+               .bytesUsed(from.getBytesUsed())
+               .metadata(from.getMetadata());
       }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/BulkDeleteResponse.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/BulkDeleteResponse.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/BulkDeleteResponse.java
index c96a66f..1f841e9 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/BulkDeleteResponse.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/BulkDeleteResponse.java
@@ -22,12 +22,16 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.Map;
 
+import org.jclouds.openstack.swift.v1.features.BulkApi;
+
 import com.google.common.base.Objects;
 
 /**
- * @see <a
- *      href="http://docs.openstack.org/developer/swift/misc.html#module-swift.common.middleware.bulk">
- *      Swift Bulk Middleware</a>
+ * Represents a response from a Bulk Delete request.
+ * 
+ * @author Jeremy Daggett
+ * 
+ * @see BulkApi
  */
 public class BulkDeleteResponse {
    public static BulkDeleteResponse create(int deleted, int notFound, Map<String, String> errors) {
@@ -44,18 +48,25 @@ public class BulkDeleteResponse {
       this.errors = checkNotNull(errors, "errors");
    }
 
-   /** number of files deleted. */
-   public int deleted() {
+   /** 
+    * @return The number of files deleted.
+    * */
+   public int getDeleted() {
       return deleted;
    }
 
-   /** number of files not found. */
-   public int notFound() {
+   /** 
+    * @return The number of files not found.
+    */
+   public int getNotFound() {
       return notFound;
    }
 
-   /** For each path that failed to delete, a corresponding error response. */
-   public Map<String, String> errors() {
+   /** 
+    * @return a {@code Map<String, String>} containing each path that failed 
+    *         to be deleted and its corresponding error response.
+    */
+   public Map<String, String> getErrors() {
       return errors;
    }
 
@@ -66,9 +77,9 @@ public class BulkDeleteResponse {
       }
       if (object instanceof BulkDeleteResponse) {
          BulkDeleteResponse that = BulkDeleteResponse.class.cast(object);
-         return equal(deleted(), that.deleted()) //
-               && equal(notFound(), that.notFound()) //
-               && equal(errors(), that.errors());
+         return equal(getDeleted(), that.getDeleted())
+               && equal(getNotFound(), that.getNotFound())
+               && equal(getErrors(), that.getErrors());
       } else {
          return false;
       }
@@ -76,14 +87,14 @@ public class BulkDeleteResponse {
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(deleted(), notFound(), errors());
+      return Objects.hashCode(getDeleted(), getNotFound(), getErrors());
    }
 
    @Override
    public String toString() {
-      return toStringHelper("") //
-            .add("deleted", deleted()) //
-            .add("notFound", notFound()) //
-            .add("errors", errors()).toString();
+      return toStringHelper("")
+            .add("deleted", getDeleted())
+            .add("notFound", getNotFound())
+            .add("errors", getErrors()).toString();
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Container.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Container.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Container.java
index e75f710..9b23705 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Container.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Container.java
@@ -24,6 +24,8 @@ import java.beans.ConstructorProperties;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.jclouds.openstack.swift.v1.features.ContainerApi;
+import org.jclouds.openstack.swift.v1.options.CreateContainerOptions;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Objects.ToStringHelper;
@@ -31,9 +33,12 @@ import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableMap;
 
 /**
- * @see <a
- *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/s_listcontainers.html">api
- *      doc</a>
+ * Represents a Container in OpenStack Object Storage.
+ * 
+ * @author Adrian Cole
+ * @author Jeremy Daggett
+ * 
+ * @see ContainerApi
  */
 public class Container implements Comparable<Container> {
 
@@ -53,38 +58,46 @@ public class Container implements Comparable<Container> {
       this.metadata = metadata == null ? ImmutableMap.<String, String> of() : metadata;
    }
 
-   public String name() {
+   /**
+    * @return The name of this container.
+    */
+   public String getName() {
       return name;
    }
 
-   public long objectCount() {
+   /**
+    * @return The count of objects for this container.
+    */
+   public long getObjectCount() {
       return objectCount;
    }
 
-   public long bytesUsed() {
+   /**
+    * @return The number of bytes used by this container.
+    */
+   public long getBytesUsed() {
       return bytesUsed;
    }
 
    /**
-    * Absent except in {@link ContainerApi#get(String) GetContainer} commands.
+    * Absent except in {@link ContainerApi#get(String) Get Container} commands.
     * 
-    * When present, designates that the container is publicly readable.
+    * @return true  if this container is publicly readable, false otherwise.
     * 
     * @see CreateContainerOptions#anybodyRead()
     */
-   public Optional<Boolean> anybodyRead() {
+   public Optional<Boolean> getAnybodyRead() {
       return anybodyRead;
    }
 
    /**
-    * Empty except in {@link ContainerApi#get(String) GetContainer} commands.
-    * 
-    * <h3>Note</h3>
-    * 
+    * <h3>NOTE</h3>
     * In current swift implementations, headers keys are lower-cased. This means
     * characters such as turkish will probably not work out well.
+    * 
+    * @return a {@code Map<String, String>} containing this container's metadata.
     */
-   public Map<String, String> metadata() {
+   public Map<String, String> getMetadata() {
       return metadata;
    }
 
@@ -95,10 +108,10 @@ public class Container implements Comparable<Container> {
       }
       if (object instanceof Container) {
          final Container that = Container.class.cast(object);
-         return equal(name(), that.name()) //
-               && equal(objectCount(), that.objectCount()) //
-               && equal(bytesUsed(), that.bytesUsed()) //
-               && equal(metadata(), that.metadata());
+         return equal(getName(), that.getName())
+               && equal(getObjectCount(), that.getObjectCount())
+               && equal(getBytesUsed(), that.getBytesUsed())
+               && equal(getMetadata(), that.getMetadata());
       } else {
          return false;
       }
@@ -106,7 +119,7 @@ public class Container implements Comparable<Container> {
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(name(), objectCount(), bytesUsed(), anybodyRead(), metadata());
+      return Objects.hashCode(getName(), getObjectCount(), getBytesUsed(), getAnybodyRead(), getMetadata());
    }
 
    @Override
@@ -115,12 +128,12 @@ public class Container implements Comparable<Container> {
    }
 
    protected ToStringHelper string() {
-      return toStringHelper("").omitNullValues() //
-            .add("name", name()) //
-            .add("objectCount", objectCount()) //
-            .add("bytesUsed", bytesUsed()) //
-            .add("anybodyRead", anybodyRead().orNull()) //
-            .add("metadata", metadata());
+      return toStringHelper("").omitNullValues()
+            .add("name", getName())
+            .add("objectCount", getObjectCount())
+            .add("bytesUsed", getBytesUsed())
+            .add("anybodyRead", getAnybodyRead().orNull())
+            .add("metadata", getMetadata());
    }
 
    @Override
@@ -129,7 +142,7 @@ public class Container implements Comparable<Container> {
          return 1;
       if (this == that)
          return 0;
-      return this.name().compareTo(that.name());
+      return this.getName().compareTo(that.getName());
    }
 
    public static Builder builder() {
@@ -148,7 +161,7 @@ public class Container implements Comparable<Container> {
       protected Map<String, String> metadata = ImmutableMap.of();
 
       /**
-       * @see Container#name()
+       * @see Container#getName()
        */
       public Builder name(String name) {
          this.name = checkNotNull(name, "name");
@@ -156,7 +169,7 @@ public class Container implements Comparable<Container> {
       }
 
       /**
-       * @see Container#objectCount()
+       * @see Container#getObjectCount()
        */
       public Builder objectCount(long objectCount) {
          this.objectCount = objectCount;
@@ -164,7 +177,7 @@ public class Container implements Comparable<Container> {
       }
 
       /**
-       * @see Container#bytesUsed()
+       * @see Container#getBytesUsed()
        */
       public Builder bytesUsed(long bytesUsed) {
          this.bytesUsed = bytesUsed;
@@ -172,7 +185,7 @@ public class Container implements Comparable<Container> {
       }
 
       /**
-       * @see Container#anybodyRead()
+       * @see Container#getAnybodyRead()
        */
       public Builder anybodyRead(Boolean anybodyRead) {
          this.anybodyRead = Optional.fromNullable(anybodyRead);
@@ -180,10 +193,10 @@ public class Container implements Comparable<Container> {
       }
 
       /**
-       * Will lower-case all metadata keys due to a swift implementation
-       * decision.
+       * <h3>NOTE</h3>
+       * This method will lower-case all metadata keys.
        * 
-       * @see Container#metadata()
+       * @see Container#getMetadata()
        */
       public Builder metadata(Map<String, String> metadata) {
          ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String> builder();
@@ -199,11 +212,11 @@ public class Container implements Comparable<Container> {
       }
 
       public Builder fromContainer(Container from) {
-         return name(from.name()) //
-               .objectCount(from.objectCount()) //
-               .bytesUsed(from.bytesUsed()) //
-               .anybodyRead(from.anybodyRead().orNull()) //
-               .metadata(from.metadata());
+         return name(from.getName())
+               .objectCount(from.getObjectCount())
+               .bytesUsed(from.getBytesUsed())
+               .anybodyRead(from.getAnybodyRead().orNull())
+               .metadata(from.getMetadata());
       }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ExtractArchiveResponse.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ExtractArchiveResponse.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ExtractArchiveResponse.java
index 5644377..e656174 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ExtractArchiveResponse.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ExtractArchiveResponse.java
@@ -22,12 +22,16 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.Map;
 
+import org.jclouds.openstack.swift.v1.features.BulkApi;
+
 import com.google.common.base.Objects;
 
 /**
- * @see <a
- *      href="http://docs.openstack.org/developer/swift/misc.html#module-swift.common.middleware.bulk">
- *      Swift Bulk Middleware</a>
+ * Represents a response from an Extract Archive request.
+ *
+ * @author Jeremy Daggett
+ * 
+ * @see BulkApi
  */
 public class ExtractArchiveResponse {
    public static ExtractArchiveResponse create(int created, Map<String, String> errors) {
@@ -42,13 +46,18 @@ public class ExtractArchiveResponse {
       this.errors = checkNotNull(errors, "errors");
    }
 
-   /** number of files created. */
-   public int created() {
+   /** 
+    * @return The number of files created.
+    */
+   public int getCreated() {
       return created;
    }
 
-   /** For each path that failed to create, a corresponding error response. */
-   public Map<String, String> errors() {
+   /** 
+    * @return a {@code Map<String, String>} containing each path that failed 
+    *         to be created and its corresponding error response.
+    */
+   public Map<String, String> getErrors() {
       return errors;
    }
 
@@ -59,8 +68,8 @@ public class ExtractArchiveResponse {
       }
       if (object instanceof ExtractArchiveResponse) {
          ExtractArchiveResponse that = ExtractArchiveResponse.class.cast(object);
-         return equal(created(), that.created()) //
-               && equal(errors(), that.errors());
+         return equal(getCreated(), that.getCreated())
+               && equal(getErrors(), that.getErrors());
       } else {
          return false;
       }
@@ -68,13 +77,13 @@ public class ExtractArchiveResponse {
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(created(), errors());
+      return Objects.hashCode(getCreated(), getErrors());
    }
 
    @Override
    public String toString() {
-      return toStringHelper("") //
-            .add("created", created()) //
-            .add("errors", errors()).toString();
+      return toStringHelper("")
+            .add("created", getCreated())
+            .add("errors", getErrors()).toString();
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
index 350e8e1..c7977c1 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
@@ -20,8 +20,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.util.List;
 
+import org.jclouds.openstack.swift.v1.features.ObjectApi;
+
 import com.google.common.collect.ForwardingList;
 
+/**
+ * Represents a list of objects in a container.
+ * 
+ * @author Jeremy Daggett
+ * 
+ * @see Container 
+ * @see SwiftObject
+ * @see ObjectApi#list()
+ */
 public class ObjectList extends ForwardingList<SwiftObject> {
 
    public static ObjectList create(List<SwiftObject> objects, Container container) {
@@ -36,7 +47,10 @@ public class ObjectList extends ForwardingList<SwiftObject> {
       this.container = checkNotNull(container, "container");
    }
 
-   public Container container() {
+   /**
+    * @return the parent {@link Container} the objects reside in.
+    */
+   public Container getContainer() {
       return container;
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Segment.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Segment.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Segment.java
index 3d24b05..d144c5c 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Segment.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/Segment.java
@@ -20,14 +20,17 @@ import static com.google.common.base.Objects.equal;
 import static com.google.common.base.Objects.toStringHelper;
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import org.jclouds.openstack.swift.v1.features.StaticLargeObjectApi;
+
 import com.google.common.base.Objects;
 
 /**
- * One piece of a multi-part upload.
+ * Represents a single segment of a multi-part upload.
+ * 
+ * @author Adrian Cole
+ * @author Jeremy Daggett
  * 
- * @see <a
- *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/static-large-objects.html">api
- *      doc</a>
+ * @see StaticLargeObjectApi
  */
 public class Segment {
 
@@ -42,22 +45,23 @@ public class Segment {
    }
 
    /**
-    * {@code /container/objectName} which corresponds to the path of
-    * {@link SwiftObject#uri()}.
+    * @return The container and object name in the format: {@code <container-name>/<object-name>}
     */
-   public String path() {
+   public String getPath() {
       return path;
    }
 
    /**
-    * Corresponds to the {@code ETag} header of the response, and is usually the
-    * MD5 checksum of the object
+    * @return The ETag of the content of the segment object.
     */
-   public String etag() {
+   public String getEtag() {
       return etag;
    }
 
-   public long sizeBytes() {
+   /**
+    * @return The size of the segment object.
+    */
+   public long getSizeBytes() {
       return size_bytes;
    }
 
@@ -68,9 +72,9 @@ public class Segment {
       }
       if (object instanceof Segment) {
          Segment that = Segment.class.cast(object);
-         return equal(path(), that.path()) //
-               && equal(etag(), that.etag()) //
-               && equal(sizeBytes(), that.sizeBytes());
+         return equal(getPath(), that.getPath())
+               && equal(getEtag(), that.getEtag())
+               && equal(getSizeBytes(), that.getSizeBytes());
       } else {
          return false;
       }
@@ -78,15 +82,15 @@ public class Segment {
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(path(), etag(), sizeBytes());
+      return Objects.hashCode(getPath(), getEtag(), getSizeBytes());
    }
 
    @Override
    public String toString() {
-      return toStringHelper("") //
-            .add("path", path()) //
-            .add("etag", etag()) //
-            .add("sizeBytes", sizeBytes()).toString();
+      return toStringHelper("")
+            .add("path", getPath())
+            .add("etag", getEtag())
+            .add("sizeBytes", getSizeBytes()).toString();
    }
 
    public static Builder builder() {
@@ -99,7 +103,7 @@ public class Segment {
       protected long sizeBytes;
 
       /**
-       * @see Segment#path()
+       * @see Segment#getPath()
        */
       public Builder path(String path) {
          this.path = path;
@@ -107,7 +111,7 @@ public class Segment {
       }
 
       /**
-       * @see Segment#etag()
+       * @see Segment#getEtag()
        */
       public Builder etag(String etag) {
          this.etag = etag;
@@ -115,7 +119,7 @@ public class Segment {
       }
 
       /**
-       * @see Segment#sizeBytes()
+       * @see Segment#getSizeBytes()
        */
       public Builder sizeBytes(long sizeBytes) {
          this.sizeBytes = sizeBytes;

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/SwiftObject.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/SwiftObject.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/SwiftObject.java
index 923e6c2..953a4f5 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/SwiftObject.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/SwiftObject.java
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import org.jclouds.io.Payload;
+import org.jclouds.openstack.swift.v1.features.ObjectApi;
 
 import com.google.common.base.Objects;
 import com.google.common.base.Objects.ToStringHelper;
@@ -34,9 +35,12 @@ import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Multimap;
 
 /**
- * @see <a
- *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/retrieve-object.html">api
- *      doc</a>
+ * Represents an object in OpenStack Object Storage.
+ * 
+ * @author Adrian Cole
+ * @author Jeremy Daggett
+ * 
+ * @see ObjectApi
  */
 public class SwiftObject implements Comparable<SwiftObject> {
 
@@ -59,52 +63,62 @@ public class SwiftObject implements Comparable<SwiftObject> {
       this.payload = checkNotNull(payload, "payload of %s", name);
    }
 
-   public String name() {
+   /**
+    * @return The name of this object.
+    */
+   public String getName() {
       return name;
    }
 
    /**
-    * http location of the object, accessible if its container is
-    * {@link CreateContainerOptions#publicRead}.
+    * @return The {@link URI} for this object.
     */
-   public URI uri() {
+   public URI getUri() {
       return uri;
    }
 
    /**
-    * Corresponds to the {@code ETag} header of the response, and is usually the
-    * MD5 checksum of the object
+    * @return The ETag of the content of this object.
     */
-   public String etag() {
+   public String getEtag() {
       return etag;
    }
 
-   public Date lastModified() {
+   /**
+    * @return The {@link Date} that this object was last modified.
+    */
+   public Date getLastModified() {
       return lastModified;
    }
 
-   public Multimap<String, String> headers() {
+   /**
+    * @return The HTTP headers for this object.
+    */
+   public Multimap<String, String> getHeaders() {
       return headers;
    }
 
    /**
-    * Empty except in {@link ObjectApi#head(String) GetObjectMetadata} or
-    * {@link ObjectApi#get(String) GetObject} commands.
-    * 
-    * <h3>Note</h3>
-    * 
+    * <h3>NOTE</h3>
     * In current swift implementations, headers keys are lower-cased. This means
     * characters such as turkish will probably not work out well.
+    * 
+    * @return a {@code Map<String, String>} containing this object's metadata. The map is empty
+    *         except in {@link ObjectApi#head(String) GetObjectMetadata} or
+    *         {@link ObjectApi#get(String) GetObject} commands.
     */
-   public Map<String, String> metadata() {
+   public Map<String, String> getMetadata() {
       return metadata;
    }
 
    /**
-    * Only has a {@link Payload#getInput()} when retrieved via the
+    * <h3>NOTE</h3>
+    * The object will only have a {@link Payload#getInput()} when retrieved via the
     * {@link ObjectApi#get(String) GetObject} command.
+    * 
+    * @return The {@link Payload} for this object.
     */
-   public Payload payload() {
+   public Payload getPayload() {
       return payload;
    }
 
@@ -115,9 +129,9 @@ public class SwiftObject implements Comparable<SwiftObject> {
       }
       if (object instanceof SwiftObject) {
          final SwiftObject that = SwiftObject.class.cast(object);
-         return equal(name(), that.name()) //
-               && equal(uri(), that.uri()) //
-               && equal(etag(), that.etag());
+         return equal(getName(), that.getName())
+               && equal(getUri(), that.getUri())
+               && equal(getEtag(), that.getEtag());
       } else {
          return false;
       }
@@ -125,7 +139,7 @@ public class SwiftObject implements Comparable<SwiftObject> {
 
    @Override
    public int hashCode() {
-      return Objects.hashCode(name(), uri(), etag());
+      return Objects.hashCode(getName(), getUri(), getEtag());
    }
 
    @Override
@@ -134,12 +148,12 @@ public class SwiftObject implements Comparable<SwiftObject> {
    }
 
    protected ToStringHelper string() {
-      return toStringHelper("") //
-            .add("name", name()) //
-            .add("uri", uri()) //
-            .add("etag", etag()) //
-            .add("lastModified", lastModified()) //
-            .add("metadata", metadata());
+      return toStringHelper("")
+            .add("name", getName())
+            .add("uri", getUri())
+            .add("etag", getEtag())
+            .add("lastModified", getLastModified())
+            .add("metadata", getMetadata());
    }
 
    @Override
@@ -148,7 +162,7 @@ public class SwiftObject implements Comparable<SwiftObject> {
          return 1;
       if (this == that)
          return 0;
-      return this.name().compareTo(that.name());
+      return this.getName().compareTo(that.getName());
    }
 
    public static Builder builder() {
@@ -169,7 +183,7 @@ public class SwiftObject implements Comparable<SwiftObject> {
       protected Map<String, String> metadata = ImmutableMap.of();
 
       /**
-       * @see SwiftObject#name()
+       * @see SwiftObject#getName()
        */
       public Builder name(String name) {
          this.name = checkNotNull(name, "name");
@@ -177,7 +191,7 @@ public class SwiftObject implements Comparable<SwiftObject> {
       }
 
       /**
-       * @see SwiftObject#uri()
+       * @see SwiftObject#getUri()
        */
       public Builder uri(URI uri) {
          this.uri = checkNotNull(uri, "uri");
@@ -185,7 +199,7 @@ public class SwiftObject implements Comparable<SwiftObject> {
       }
 
       /**
-       * @see SwiftObject#etag()
+       * @see SwiftObject#getEtag()
        */
       public Builder etag(String etag) {
          this.etag = etag;
@@ -193,7 +207,7 @@ public class SwiftObject implements Comparable<SwiftObject> {
       }
 
       /**
-       * @see SwiftObject#lastModified()
+       * @see SwiftObject#getLastModified()
        */
       public Builder lastModified(Date lastModified) {
          this.lastModified = lastModified;
@@ -201,13 +215,16 @@ public class SwiftObject implements Comparable<SwiftObject> {
       }
 
       /**
-       * @see SwiftObject#payload()
+       * @see SwiftObject#getPayload()
        */
       public Builder payload(Payload payload) {
          this.payload = payload;
          return this;
       }
 
+      /**
+       * @see SwiftObject#getHeaders()
+       */
       public Builder headers(Multimap<String, String> headers) {
          this.headers = headers;
          return this;
@@ -217,7 +234,7 @@ public class SwiftObject implements Comparable<SwiftObject> {
        * Will lower-case all metadata keys due to a swift implementation
        * decision.
        * 
-       * @see SwiftObject#metadata()
+       * @see SwiftObject#getMetadata()
        */
       public Builder metadata(Map<String, String> metadata) {
          ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String> builder();
@@ -233,13 +250,13 @@ public class SwiftObject implements Comparable<SwiftObject> {
       }
 
       public Builder fromObject(SwiftObject from) {
-         return name(from.name()) //
-               .uri(from.uri()) //
-               .etag(from.etag()) //
-               .lastModified(from.lastModified()) //
-               .headers(from.headers()) //
-               .metadata(from.metadata()) //
-               .payload(from.payload());
+         return name(from.getName())
+               .uri(from.getUri())
+               .etag(from.getEtag())
+               .lastModified(from.getLastModified())
+               .headers(from.getHeaders())
+               .metadata(from.getMetadata())
+               .payload(from.getPayload());
       }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
index 9736112..57f9ef0 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.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.ACCOUNT_TEMPORARY_URL_KEY;
 
 import java.util.Map;
 
@@ -39,16 +40,15 @@ import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.ResponseParser;
 
 /**
- * Provides access to the Swift Account API.
+ * Provides access to the Swift Account API features.
  * 
  * <p/>
  * Account metadata prefixed with {@code X-Account-Meta-} will be converted
  * appropriately using a binder/parser.
  * 
+ * @author Jeremy Daggett
+ * 
  * @see {@link Account}
- * @see <a
- *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/storage-account-services.html">
- *      Storage Account Services API</a>
  */
 @RequestFilters(AuthenticateRequest.class)
 @Consumes(APPLICATION_JSON)
@@ -57,70 +57,51 @@ public interface AccountApi {
    /**
     * Gets the {@link Account}.
     * 
-    * @return the Account.
-    * 
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/retrieve-account-metadata.html">
-    *      Get Account Metadata API</a>
+    * @return The {@link Account} object.
     */
-   @Named("GetAccount")
+   @Named("account:get")
    @HEAD
    @ResponseParser(ParseAccountFromHeaders.class)
    @Path("/")
    Account get();
 
    /**
-    * Creates or updates the Account metadata.
-    * 
-    * @param metadata
-    *           the Account metadata to create or update.
+    * Creates or updates the {@link Account} metadata.
     * 
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/create-update-account-metadata.html">
-    *      Create or Update Account Metadata API</a>
+    * @param metadata  the metadata to create or update.
     * 
-    * @return <code>true</code> if the Account Metadata was successfully created
-    *         or updated, false if not.
+    * @return {@code true} if the metadata was successfully created or updated,
+    *         {@code false} if not.
     */
-   @Named("UpdateAccountMetadata")
+   @Named("account:updateMetadata")
    @POST
    @Fallback(FalseOnNotFoundOr404.class)
    @Path("/")
    boolean updateMetadata(@BinderParam(BindAccountMetadataToHeaders.class) Map<String, String> metadata);
 
    /**
-    * Replaces the {@link Account#temporaryUrlKey()}.
+    * Replaces the temporary URL key for the {@link Account}.
     *
-    * @param metadata
-    *           the Account metadata to create or update.
+    * @param temporaryUrlKey  the temporary URL key to update.
     *
-    * @see <a
-    *      href="http://docs.openstack.org/trunk/config-reference/content/object-storage-tempurl.html">
-    *      Temporary URL Documentation</a>
-    *
-    * @return <code>true</code> if the Temporary URL Key was successfully created
-    *         or updated, false if not.
+    * @return {@code true} if the temporary URL key was successfully updated,
+    *         {@code false} if not.
     */
-   @Named("UpdateAccountMetadata")
+   @Named("account:updateTemporaryUrlKey")
    @POST
    @Fallback(FalseOnNotFoundOr404.class)
    @Path("/")
-   boolean updateTemporaryUrlKey(@HeaderParam("X-Account-Meta-Temp-URL-Key") String temporaryUrlKey);
+   boolean updateTemporaryUrlKey(@HeaderParam(ACCOUNT_TEMPORARY_URL_KEY) String temporaryUrlKey);
 
    /**
-    * Deletes Account metadata.
-    * 
-    * @param metadata
-    *           the Account metadata to delete.
+    * Deletes metadata from the {@link Account}.
     * 
-    * @return <code>true</code> if the Account Metadata was successfully
-    *         deleted, false if not.
+    * @param metadata  the metadata to delete.
     * 
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/delete-account-metadata.html">
-    *      Delete Account Metadata API</a>
+    * @return {@code true} if the metadata was successfully deleted,
+    *         {@code false} if not.
     */
-   @Named("DeleteAccountMetadata")
+   @Named("account:deleteMetadata")
    @POST
    @Fallback(FalseOnNotFoundOr404.class)
    @Path("/")

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
index 60eb851..ba5825e 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
@@ -46,15 +46,8 @@ import com.google.common.base.Joiner;
 /**
  * Provides access to the Swift Bulk API.
  * 
- * <h3>Note</h3>
- * 
- * As of the Grizzly release, these operations occur <a
- * href="https://blueprints.launchpad.net/swift/+spec/concurrent-bulk">serially
- * on the backend</a>.
- * 
- * @see <a
- *      href="http://docs.openstack.org/developer/swift/misc.html#module-swift.common.middleware.bulk">
- *      Swift Bulk Middleware</a>
+ * @author Adrian Cole
+ * @author Jeremy Daggett
  */
 @RequestFilters(AuthenticateRequest.class)
 @Consumes(APPLICATION_JSON)
@@ -64,15 +57,15 @@ public interface BulkApi {
     * Extracts a tar archive at the path specified as {@code path}.
     * 
     * @param path
-    *           path to extract under, if not empty string.
+    *           the path to extract under.
     * @param tar
-    *           valid tar archive
+    *           a valid tar archive.
     * @param format
     *           one of {@code tar}, {@code tar.gz}, or {@code tar.bz2}
     * 
-    * @return {@link BulkDeleteResponse#errors()} are empty on success.
+    * @return {@link BulkDeleteResponse#getErrors()} are empty on success.
     */
-   @Named("ExtractArchive")
+   @Named("bulk:extractArchive")
    @PUT
    @Path("/{path}")
    ExtractArchiveResponse extractArchive(@PathParam("path") String path,
@@ -85,9 +78,9 @@ public interface BulkApi {
     *           format of {@code container}, for an empty container, or
     *           {@code container/object} for an object.
     * 
-    * @return {@link BulkDeleteResponse#errors()} are empty on success.
+    * @return {@link BulkDeleteResponse#getErrors()} are empty on success.
     */
-   @Named("BulkDelete")
+   @Named("bulk:delete")
    @DELETE
    @Path("/")
    @QueryParams(keys = "bulk-delete")

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
index d9438fa..e698e2f 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
@@ -29,7 +29,6 @@ import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
-import javax.ws.rs.QueryParam;
 
 import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
@@ -42,6 +41,7 @@ import org.jclouds.openstack.swift.v1.domain.Container;
 import org.jclouds.openstack.swift.v1.functions.FalseOnAccepted;
 import org.jclouds.openstack.swift.v1.functions.ParseContainerFromHeaders;
 import org.jclouds.openstack.swift.v1.options.CreateContainerOptions;
+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.QueryParams;
@@ -51,13 +51,11 @@ import org.jclouds.rest.annotations.ResponseParser;
 import com.google.common.collect.FluentIterable;
 
 /**
- * Storage Container Services
+ * Provides access to the Swift Container API features.
  * 
  * @author Adrian Cole
  * @author Zack Shoylev
- * @see <a href=
- *      "http://docs.openstack.org/api/openstack-object-storage/1.0/content/storage-container-services.html"
- *      >api doc</a>
+ * @author Jeremy Daggett
  */
 @RequestFilters(AuthenticateRequest.class)
 @Consumes(APPLICATION_JSON)
@@ -66,46 +64,41 @@ public interface ContainerApi {
    /**
     * Lists up to 10,000 containers.
     * 
-    * @return a list of existing storage containers ordered by name.
+    * @return a list of {@link Container containers} ordered by name.
     */
-   @Named("ListContainers")
+   @Named("container:list")
    @GET
    @QueryParams(keys = "format", values = "json")
    @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
    @Path("/")
-   FluentIterable<Container> listFirstPage();
+   FluentIterable<Container> list();
 
    /**
-    * Lists up to 10,000 containers, starting at {@code marker}
+    * Lists containers with the supplied {@link ListContainerOptions}.
     * 
-    * @param marker
-    *           lexicographic position to start list.
+    * @param options
+    *          the options to control the output list.
     * 
-    * @return a list of existing storage containers ordered by name.
+    * @return a list of {@link Container containers} ordered by name.
     */
-   @Named("ListContainers")
+   @Named("container:list")
    @GET
    @QueryParams(keys = "format", values = "json")
    @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
    @Path("/")
-   FluentIterable<Container> listAt(@QueryParam("marker") String marker);
+   FluentIterable<Container> list(ListContainerOptions options);
 
    /**
     * Creates a container, if not already present.
     * 
     * @param containerName
-    *           corresponds to {@link Container#name()}.
+    *           corresponds to {@link Container#getName()}.
     * @param options
-    *           configuration such as <a href=
-    *           "http://docs.openstack.org/api/openstack-object-storage/1.0/content/special-metadata-acls.html"
-    *           >public read access</a>.
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/create-container.html">
-    *      Create Container API</a>
+    *           the options to use when creating the container.
     * 
-    * @return <code>false</code> if the container already existed.
+    * @return {@code true} if the container was created, {@code false} if the container already existed.
     */
-   @Named("CreateContainer")
+   @Named("container:createIfAbsent")
    @PUT
    @ResponseParser(FalseOnAccepted.class)
    @Path("/{containerName}")
@@ -115,14 +108,11 @@ public interface ContainerApi {
     * Gets the {@link Container}.
     * 
     * @param containerName
-    *           corresponds to {@link Container#name()}.
-    * @return the Container or null, if not found.
+    *           corresponds to {@link Container#getName()}.
     * 
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/retrieve-Container-metadata.html">
-    *      Get Container Metadata API</a>
+    * @return the {@link Container}, or {@code null} if not found.
     */
-   @Named("GetContainer")
+   @Named("container:get")
    @HEAD
    @ResponseParser(ParseContainerFromHeaders.class)
    @Fallback(NullOnNotFoundOr404.class)
@@ -131,21 +121,17 @@ public interface ContainerApi {
    Container get(@PathParam("containerName") String containerName);
 
    /**
-    * Creates or updates the Container metadata.
+    * Creates or updates the {@link Container} metadata.
     * 
     * @param containerName
-    *           corresponds to {@link Container#name()}.
+    *           the container name corresponding to {@link Container#getName()}.
     * @param metadata
-    *           the Container 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 Container Metadata API</a>
+    *           the container metadata to create or update.
     * 
-    * @return <code>true</code> if the Container Metadata was successfully
-    *         created or updated, false if not.
+    * @return {@code true} if the container metadata was successfully created or updated,
+    *         {@code false} if not.
     */
-   @Named("UpdateContainerMetadata")
+   @Named("container:updateMetadata")
    @POST
    @Fallback(FalseOnNotFoundOr404.class)
    @Path("/{containerName}")
@@ -153,21 +139,17 @@ public interface ContainerApi {
          @BinderParam(BindContainerMetadataToHeaders.class) Map<String, String> metadata);
 
    /**
-    * Deletes Container metadata.
+    * Deletes {@link Container} metadata.
     * 
     * @param containerName
-    *           corresponds to {@link Container#name()}.
+    *           corresponds to {@link Container#getName()}.
     * @param metadata
-    *           the Container metadata to delete.
+    *           the container metadata to delete.
     * 
-    * @return <code>true</code> if the Container Metadata was successfully
-    *         deleted, false if not.
-    * 
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/delete-container-metadata.html">
-    *      Delete Container Metadata API</a>
+    * @return {@code true} if the container metadata was successfully deleted, 
+    *         {@code false} if not.
     */
-   @Named("DeleteContainerMetadata")
+   @Named("container:deleteMetadata")
    @POST
    @Fallback(FalseOnNotFoundOr404.class)
    @Path("/{containerName}")
@@ -175,19 +157,16 @@ public interface ContainerApi {
          @BinderParam(BindRemoveContainerMetadataToHeaders.class) Map<String, String> metadata);
 
    /**
-    * Deletes a container, if empty.
+    * Deletes a {@link Container}, if empty.
     * 
     * @param containerName
-    *           corresponds to {@link Container#name()}.
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/delete-container.html">
-    *      Delete Container API</a>
+    *           corresponds to {@link Container#getName()}.
+    * 
+    * @return {@code false} if the container was not present.
     * 
-    * @return <code>false</code> if the container was not present.
-    * @throws IllegalStateException
-    *            when the container wasn't empty.
+    * @throws IllegalStateException if the container was not empty.
     */
-   @Named("DeleteContainer")
+   @Named("container:deleteIfEmpty")
    @DELETE
    @Fallback(FalseOnNotFoundOr404.class)
    @Path("/{containerName}")

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 374bfa6..97c38b0 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
@@ -57,9 +57,10 @@ import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.ResponseParser;
 
 /**
- * @see <a href=
- *      "http://docs.openstack.org/api/openstack-object-storage/1.0/content/storage-object-services.html"
- *      >api doc</a>
+ * Provides access to the Swift Object API features.
+ * 
+ * @author Adrian Cole
+ * @author Jeremy Daggett
  */
 @RequestFilters(AuthenticateRequest.class)
 @Consumes(APPLICATION_JSON)
@@ -68,12 +69,12 @@ public interface ObjectApi {
    /**
     * Lists up to 10,000 objects.
     * 
-    * @param options
-    *          options to control the output list.
-    *          
-    * @return an {@link ObjectList} of {@link SwiftObject} ordered by name or null.
+    * @param options  
+    *           the {@link ListContainerOptions} for controlling the returned list.
+    * 
+    * @return an {@link ObjectList} of {@link SwiftObject} ordered by name or {@code null}.
     */
-   @Named("ListObjects")
+   @Named("object:list")
    @GET
    @QueryParams(keys = "format", values = "json")
    @ResponseParser(ParseObjectListFromResponse.class)
@@ -83,21 +84,18 @@ public interface ObjectApi {
    ObjectList list(ListContainerOptions options);
 
    /**
-    * Creates or updates an object.
+    * Creates or updates a {@link SwiftObject}.
     * 
     * @param objectName
-    *           corresponds to {@link SwiftObject#name()}.
+    *           corresponds to {@link SwiftObject#getName()}.
     * @param payload
-    *           corresponds to {@link SwiftObject#payload()}.
+    *           corresponds to {@link SwiftObject#getPayload()}.
     * @param metadata
-    *           corresponds to {@link SwiftObject#metadata()}.
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/create-update-object.html">
-    *      Create or Update Object API</a>
+    *           corresponds to {@link SwiftObject#getMetadata()}.
     * 
-    * @return {@link SwiftObject#etag()} of the object.
+    * @return {@link SwiftObject#getEtag()} of the object.
     */
-   @Named("CreateOrUpdateObject")
+   @Named("object:replace")
    @PUT
    @ResponseParser(ETagHeader.class)
    @Path("/{objectName}")
@@ -105,18 +103,14 @@ public interface ObjectApi {
          @BinderParam(BindObjectMetadataToHeaders.class) Map<String, String> metadata);
 
    /**
-    * Gets the {@link SwiftObject} metadata without its
-    * {@link Payload#getInput() body}.
+    * Gets the {@link SwiftObject} metadata without its {@link Payload#getInput() body}.
     * 
     * @param objectName
-    *           corresponds to {@link SwiftObject#name()}.
-    * @return the {@link SwiftObject} or null, if not found.
+    *           corresponds to {@link SwiftObject#getName()}.
     * 
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/retrieve-object-metadata.html">
-    *      Get Object Metadata API</a>
+    * @return the {@link SwiftObject} or {@code null}, if not found.
     */
-   @Named("GetObjectMetadata")
+   @Named("object:head")
    @HEAD
    @ResponseParser(ParseObjectFromResponse.class)
    @Fallback(NullOnNotFoundOr404.class)
@@ -128,17 +122,13 @@ public interface ObjectApi {
     * Gets the {@link SwiftObject} including its {@link Payload#getInput() body}.
     * 
     * @param objectName
-    *           corresponds to {@link SwiftObject#name()}.
+    *           corresponds to {@link SwiftObject#getName()}.
     * @param options
     *           options to control the download.
     * 
-    * @return the Object or null, if not found.
-    * 
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/retrieve-object.html">
-    *      Get Object API</a>
+    * @return the {@link SwiftObject} or {@code null}, if not found.
     */
-   @Named("GetObject")
+   @Named("object:get")
    @GET
    @ResponseParser(ParseObjectFromResponse.class)
    @Fallback(NullOnNotFoundOr404.class)
@@ -150,18 +140,14 @@ public interface ObjectApi {
     * Creates or updates the metadata for a {@link SwiftObject}.
     * 
     * @param objectName
-    *           corresponds to {@link SwiftObject#name()}.
+    *           corresponds to {@link SwiftObject#getName()}.
     * @param metadata
     *           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} if the metadata was successfully created
-    *         or updated, false if not.
+    * @return {@code true} if the metadata was successfully created or updated, 
+    *         {@code false} if not.
     */
-   @Named("UpdateObjectMetadata")
+   @Named("object:updateMetadata")
    @POST
    @Fallback(FalseOnNotFoundOr404.class)
    @Path("/{objectName}")
@@ -172,17 +158,14 @@ public interface ObjectApi {
     * Deletes the metadata from a {@link SwiftObject}.
     * 
     * @param objectName
-    *           corresponds to {@link SwiftObject#name()}.
+    *           corresponds to {@link SwiftObject#getName()}.
     * @param metadata
-    *           corresponds to {@link SwiftObject#metadata()}.
+    *           corresponds to {@link SwiftObject#getMetadata()}.
     * 
-    * @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">
-    *      Delete Object Metadata API</a>
+    * @return {@code true} if the metadata was successfully deleted, 
+    *         {@code false} if not.
     */
-   @Named("DeleteObjectMetadata")
+   @Named("object:deleteMetadata")
    @POST
    @Fallback(FalseOnNotFoundOr404.class)
    @Path("/{objectName}")
@@ -193,20 +176,19 @@ public interface ObjectApi {
     * Deletes an object, if present.
     * 
     * @param objectName
-    *           corresponds to {@link SwiftObject#name()}.
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/delete-object.html">
-    *      Delete Object API</a>
+    *           corresponds to {@link SwiftObject#getName()}.
     */
-   @Named("DeleteObject")
+   @Named("object:delete")
    @DELETE
    @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.
+    * Copies an object from one container to another. 
+    * 
+    * <h3>NOTE</h3>
+    * This is a server side copy.
     * 
     * @param destinationObject
     *           the destination object name.
@@ -214,15 +196,12 @@ public interface ObjectApi {
     *           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
+    * @return {@code true} if the object was successfully copied, {@code false} if not.
     * 
-    * @see <a
-    *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/copy-object.html">
-    *      Copy Object API</a>
+    * @throws CopyObjectException if the source or destination container do not exist.
     */
-   @Named("CopyObject")
+   @Named("object:copy")
    @PUT
    @Path("/{destinationObject}")
    @Headers(keys = OBJECT_COPY_FROM, values = "/{sourceContainer}/{sourceObject}")
@@ -230,5 +209,4 @@ public interface ObjectApi {
    boolean copy(@PathParam("destinationObject") String destinationObject,
                 @PathParam("sourceContainer") String sourceContainer,
                 @PathParam("sourceObject") String sourceObject);
-
 }


[3/5] JCLOUDS-423 - Adds support for Rackspace Cloud Files API - Added support for CloudFilesApi/CDNApi - Added mock/live tests - Refactored listFirstPage() and listAt() API methods to list() and listWithOptions(…) - General Swift API cleanup: docs and t

Posted by za...@apache.org.
http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 4559983..db835fd 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
@@ -35,6 +35,7 @@ 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.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.ObjectList;
 import org.jclouds.openstack.swift.v1.domain.SwiftObject;
 import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
@@ -48,18 +49,22 @@ import org.testng.annotations.Test;
 import com.google.common.collect.ImmutableMap;
 
 /**
+ * Provides live tests for the {@link ObjectApi}.
+ * 
  * @author Adrian Cole
+ * @author Jeremy Daggett
  */
-@Test(groups = "live", testName = "ObjectApiLiveTest")
-public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
+@Test(groups = "live", testName = "ObjectApiLiveTest", singleThreaded = true)
+public class ObjectApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
+   
    private String name = getClass().getSimpleName();
    private String containerName = getClass().getSimpleName() + "Container";
    
-   public void copyObject() throws Exception {
-      for (String regionId : regions) {               
+   public void testCopyObject() throws Exception {
+      for (String regionId : regions) {
          // source
          String sourceContainer = "src" + containerName;
-         String sourceObject = "original.txt";
+         String sourceObjectName = "original.txt";
          String badSource = "badSource";
          
          // destination
@@ -81,29 +86,29 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
          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);
+         assertNotNull(srcApi.replace(sourceObjectName, data, ImmutableMap.<String, String> of()));
+         SwiftObject sourceObject = srcApi.get(sourceObjectName, GetOptions.NONE);
+         checkObject(sourceObject);
 
          // 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));
+         SwiftObject object = destApi.get(destinationObject, GetOptions.NONE);
+         checkObject(object);
 
          // check the copy operation 
-         assertTrue(destApi.copy(destinationObject, sourceContainer, sourceObject));
+         assertTrue(destApi.copy(destinationObject, sourceContainer, sourceObjectName));
          assertNotNull(destApi.head(destinationObject));
          
          // now get a real SwiftObject
          SwiftObject destSwiftObject = destApi.get(destinationObject, GetOptions.NONE);
-         assertEquals(Strings2.toString(destSwiftObject.payload()), stringPayload);
+         assertEquals(Strings2.toString(destSwiftObject.getPayload()), stringPayload);
          
          // test exception thrown on bad source name
          try {
-            destApi.copy(destinationObject, badSource, sourceObject);
+            destApi.copy(destinationObject, badSource, sourceObjectName);
             fail("Expected CopyObjectException");
-         } catch (CopyObjectException e) {             
-            assertEquals(e.getSourcePath(), "/" + badSource + "/" + sourceObject);
+         } catch (CopyObjectException e) {
+            assertEquals(e.getSourcePath(), "/" + badSource + "/" + sourceObjectName);
             assertEquals(e.getDestinationPath(), destinationPath);
          }
 
@@ -115,11 +120,11 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
       }
    }
 
-   public void list() throws Exception {
+   public void testList() throws Exception {
       for (String regionId : regions) {
          ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName);
-         ObjectList response = objectApi.list(new ListContainerOptions());
-         assertEquals(response.container(), api.containerApiInRegion(regionId).get(containerName));
+         ObjectList response = objectApi.list(ListContainerOptions.NONE);
+         assertEquals(response.getContainer(), api.containerApiInRegion(regionId).get(containerName));
          assertNotNull(response);
          for (SwiftObject object : response) {
             checkObject(object);
@@ -127,97 +132,81 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
       }
    }
 
-   static void checkObject(SwiftObject object) {
-      assertNotNull(object.name());
-      assertNotNull(object.uri());
-      assertNotNull(object.etag());
-      assertTrue(object.lastModified().getTime() <= System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5));
-      assertNotNull(object.payload().getContentMetadata().getContentLength());
-      assertNotNull(object.payload().getContentMetadata().getContentType());
-   }
-
-   public void metadata() throws Exception {
+   public void testMetadata() throws Exception {
       for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).head(name);
-         assertEquals(object.name(), name);
+         assertEquals(object.getName(), name);
          checkObject(object);
-         assertEquals(toStringAndClose(object.payload().getInput()), "");
+         assertEquals(toStringAndClose(object.getPayload().getInput()), "");
       }
    }
 
-   public void get() throws Exception {
+   public void testUpdateMetadata() throws Exception {
+      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));
+         
+         SwiftObject object = objectApi.head(name);
+         for (Entry<String, String> entry : meta.entrySet()) {
+            // note keys are returned in lower-case!
+            assertEquals(object.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue(),
+                  object + " didn't have metadata: " + entry);
+         }
+      }
+   }
+
+   public void testGet() throws Exception {
       for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).get(name, GetOptions.NONE);
-         assertEquals(object.name(), name);
+         assertEquals(object.getName(), name);
          checkObject(object);
-         assertEquals(toStringAndClose(object.payload().getInput()), "swifty");
+         assertEquals(toStringAndClose(object.getPayload().getInput()), "swifty");
       }
    }
 
-   public void privateByDefault() throws Exception {
+   public void testPrivateByDefault() throws Exception {
       for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).head(name);
          try {
-            object.uri().toURL().openStream();
+            object.getUri().toURL().openStream();
             fail("shouldn't be able to access " + object);
          } catch (IOException expected) {
          }
       }
    }
 
-   public void getOptions() throws Exception {
+   public void testGetOptions() throws Exception {
       for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).get(name, tail(1));
-         assertEquals(object.name(), name);
+         assertEquals(object.getName(), name);
          checkObject(object);
-         assertEquals(toStringAndClose(object.payload().getInput()), "y");
+         assertEquals(toStringAndClose(object.getPayload().getInput()), "y");
       }
    }
 
-   public void listOptions() throws Exception {
+   public void testListOptions() throws Exception {
       String lexicographicallyBeforeName = name.substring(0, name.length() - 1);
       for (String regionId : regions) {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName)
                .list(marker(lexicographicallyBeforeName)).get(0);
-         assertEquals(object.name(), name);
+         assertEquals(object.getName(), name);
          checkObject(object);
       }
    }
 
-   public void updateMetadata() throws Exception {
-      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 {
+   public void testDeleteMetadata() throws Exception {
       for (String regionId : regions) {
          ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName);
 
          Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");
-
+          
          assertTrue(objectApi.updateMetadata(name, meta));
-         containerHasMetadata(objectApi, name, meta);
-
+         assertFalse(objectApi.head(name).getMetadata().isEmpty());
+         
          assertTrue(objectApi.deleteMetadata(name, meta));
-         SwiftObject object = objectApi.head(name);
-         for (Entry<String, String> entry : meta.entrySet()) {
-            // note keys are returned in lower-case!
-            assertFalse(object.metadata().containsKey(entry.getKey().toLowerCase()));
-         }
-      }
-   }
-
-   static void containerHasMetadata(ObjectApi objectApi, String name, Map<String, String> meta) {
-      SwiftObject object = objectApi.head(name);
-      for (Entry<String, String> entry : meta.entrySet()) {
-         // note keys are returned in lower-case!
-         assertEquals(object.metadata().get(entry.getKey().toLowerCase()), entry.getValue(), //
-               object + " didn't have metadata: " + entry);
+         assertTrue(objectApi.head(name).getMetadata().isEmpty());
       }
    }
 
@@ -240,6 +229,16 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
          api.objectApiInRegionForContainer(regionId, containerName).delete(name);
          api.containerApiInRegion(regionId).deleteIfEmpty(containerName);
       }
+      
       super.tearDown();
    }
+   
+   static void checkObject(SwiftObject object) {
+      assertNotNull(object.getName());
+      assertNotNull(object.getUri());
+      assertNotNull(object.getEtag());
+      assertTrue(object.getLastModified().getTime() <= System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5));
+      assertNotNull(object.getPayload().getContentMetadata().getContentLength());
+      assertNotNull(object.getPayload().getContentMetadata().getContentType());
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 7ceb21a..d44e308 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
@@ -22,7 +22,10 @@ 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.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_ACL_ANYBODY_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_REMOVE_METADATA_PREFIX;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
@@ -31,12 +34,6 @@ 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;
@@ -47,8 +44,6 @@ 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;
 
@@ -58,68 +53,59 @@ import com.squareup.okhttp.mockwebserver.MockResponse;
 import com.squareup.okhttp.mockwebserver.MockWebServer;
 import com.squareup.okhttp.mockwebserver.RecordedRequest;
 
-@Test
+/**
+ * Provides mock tests for the {@link ObjectApi}.
+ * 
+ * @author Adrian Cole
+ * @author Jeremy Daggett
+ */
+@Test(groups = "unit", testName = "ObjectApiMockTest")
 public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    SimpleDateFormatDateService dates = new SimpleDateFormatDateService();
 
-   String objectList = "" //
-         + "[\n" //
-         + "   {\"name\":\"test_obj_1\",\n" //
-         + "    \"hash\":\"4281c348eaf83e70ddce0e07221c3d28\",\n" //
-         + "    \"bytes\":14,\n" //
-         + "    \"content_type\":\"application\\/octet-stream\",\n" //
-         + "    \"last_modified\":\"2009-02-03T05:26:32.612278\"},\n" //
-         + "   {\"name\":\"test_obj_2\",\n" //
-         + "    \"hash\":\"b039efe731ad111bc1b0ef221c3849d0\",\n" //
-         + "    \"bytes\":64,\n" //
-         + "    \"content_type\":\"application\\/octet-stream\",\n" //
-         + "    \"last_modified\":\"2009-02-03T05:26:32.612278\"},\n" //
-         + "]";
-
    protected ImmutableList<SwiftObject> parsedObjectsForUrl(String baseUri) {
       baseUri += "v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer";
-      return ImmutableList.of(//
-            SwiftObject.builder() //
-                  .name("test_obj_1") //
-                  .uri(URI.create(baseUri + "/test_obj_1")) //
-                  .etag("4281c348eaf83e70ddce0e07221c3d28") //
-                  .payload(payload(14, "application/octet-stream")) //
-                  .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build(), //
-            SwiftObject.builder() //
-                  .name("test_obj_2") //
-                  .uri(URI.create(baseUri + "/test_obj_2")) //
-                  .etag("b039efe731ad111bc1b0ef221c3849d0") //
-                  .payload(payload(64l, "application/octet-stream")) //
+      return ImmutableList.of(
+            SwiftObject.builder()
+                  .name("test_obj_1")
+                  .uri(URI.create(baseUri + "/test_obj_1"))
+                  .etag("4281c348eaf83e70ddce0e07221c3d28")
+                  .payload(payload(14, "application/octet-stream"))
+                  .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build(),
+            SwiftObject.builder()
+                  .name("test_obj_2")
+                  .uri(URI.create(baseUri + "/test_obj_2"))
+                  .etag("b039efe731ad111bc1b0ef221c3849d0")
+                  .payload(payload(64l, "application/octet-stream"))
                   .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build());
    }
 
-   public void list() throws Exception {
+   public void testList() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(containerResponse() //
-            .addHeader("X-Container-Read", ".r:*,.rlistings") //
-            .setBody(objectList)));
+      server.enqueue(addCommonHeaders(containerResponse()
+            .addHeader(CONTAINER_READ, CONTAINER_ACL_ANYBODY_READ)
+            .setBody(stringFromResource("/object_list.json"))));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
          ObjectList objects = api.objectApiInRegionForContainer("DFW", "myContainer").list(new ListContainerOptions());
          assertEquals(objects, parsedObjectsForUrl(server.getUrl("/").toString()));
-         assertEquals(objects.container().name(), "myContainer");
-         assertTrue(objects.container().anybodyRead().get());
+         assertEquals(objects.getContainer().getName(), "myContainer");
+         assertTrue(objects.getContainer().getAnybodyRead().get());
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         assertEquals(server.takeRequest().getRequestLine(),
-               "GET /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/?format=json HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/?format=json");
       } finally {
          server.shutdown();
       }
    }
 
-   public void listOptions() throws Exception {
+   public void testListOptions() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(containerResponse().setBody(objectList)));
+      server.enqueue(addCommonHeaders(containerResponse().setBody(stringFromResource("/object_list.json"))));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -127,19 +113,18 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertEquals(objects, parsedObjectsForUrl(server.getUrl("/").toString()));
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         assertEquals(server.takeRequest().getRequestLine(),
-               "GET /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/?format=json&marker=test HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/?format=json&marker=test");
       } finally {
          server.shutdown();
       }
    }
 
-   public void replace() throws Exception {
+   public void testReplace() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(new MockResponse() //
-            .setResponseCode(201) //
+      server.enqueue(addCommonHeaders(new MockResponse()
+            .setResponseCode(201)
             .addHeader("ETag", "d9f5eb4bba4e2f2f046e54611bc8196b")));
 
       try {
@@ -149,13 +134,13 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
                      newStringPayload("swifty"), metadata), "d9f5eb4bba4e2f2f046e54611bc8196b");
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+         assertAuthentication(server);         
          RecordedRequest replace = server.takeRequest();
-         assertEquals(replace.getRequestLine(),
-               "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
+         assertRequest(replace, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject");
+
          assertEquals(new String(replace.getBody()), "swifty");
          for (Entry<String, String> entry : metadata.entrySet()) {
-            assertEquals(replace.getHeader("x-object-meta-" + entry.getKey().toLowerCase()), entry.getValue());
+            assertEquals(replace.getHeader(OBJECT_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
          }
       } finally {
          server.shutdown();
@@ -163,31 +148,30 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    }
 
    /** upper-cases first char, and lower-cases rest!! **/
-   public void headKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
+   public void testHeadKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(objectResponse() //
+      server.enqueue(addCommonHeaders(objectResponse()
             // note silly casing
-            .addHeader("X-Object-Meta-Apiname", "swift") //
-            .addHeader("X-Object-Meta-Apiversion", "v1.1")));
+            .addHeader(OBJECT_METADATA_PREFIX + "Apiname", "swift")
+            .addHeader(OBJECT_METADATA_PREFIX + "Apiversion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
          SwiftObject object = api.objectApiInRegionForContainer("DFW", "myContainer").head("myObject");
-         assertEquals(object.name(), "myObject");
-         assertEquals(object.etag(), "8a964ee2a5e88be344f36c22562a6486");
-         assertEquals(object.lastModified(), dates.rfc822DateParse("Fri, 12 Jun 2010 13:40:18 GMT"));
-         for (Entry<String, String> entry : object.metadata().entrySet()) {
-            assertEquals(object.metadata().get(entry.getKey().toLowerCase()), entry.getValue());
+         assertEquals(object.getName(), "myObject");
+         assertEquals(object.getEtag(), "8a964ee2a5e88be344f36c22562a6486");
+         assertEquals(object.getLastModified(), dates.rfc822DateParse("Fri, 12 Jun 2010 13:40:18 GMT"));
+         for (Entry<String, String> entry : object.getMetadata().entrySet()) {
+            assertEquals(object.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue());
          }
-         assertEquals(object.payload().getContentMetadata().getContentLength(), new Long(4));
-         assertEquals(object.payload().getContentMetadata().getContentType(), "text/plain; charset=UTF-8");
-         assertEquals(Strings2.toStringAndClose(object.payload().getInput()), "");
+         assertEquals(object.getPayload().getContentMetadata().getContentLength(), new Long(4));
+         assertEquals(object.getPayload().getContentMetadata().getContentType(), "text/plain; charset=UTF-8");
+         assertEquals(Strings2.toStringAndClose(object.getPayload().getInput()), "");
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         assertEquals(server.takeRequest().getRequestLine(),
-               "HEAD /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject");
       } finally {
          server.shutdown();
       }
@@ -196,24 +180,24 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    public void get() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(objectResponse() //
+      server.enqueue(addCommonHeaders(objectResponse()
             // note silly casing
-            .addHeader("X-Object-Meta-Apiname", "swift") //
-            .addHeader("X-Object-Meta-Apiversion", "v1.1")));
+            .addHeader(OBJECT_METADATA_PREFIX + "Apiname", "swift")
+            .addHeader(OBJECT_METADATA_PREFIX + "Apiversion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
          SwiftObject object = api.objectApiInRegionForContainer("DFW", "myContainer").get("myObject", tail(1));
-         assertEquals(object.name(), "myObject");
-         assertEquals(object.etag(), "8a964ee2a5e88be344f36c22562a6486");
-         assertEquals(object.lastModified(), dates.rfc822DateParse("Fri, 12 Jun 2010 13:40:18 GMT"));
-         for (Entry<String, String> entry : object.metadata().entrySet()) {
-            assertEquals(object.metadata().get(entry.getKey().toLowerCase()), entry.getValue());
+         assertEquals(object.getName(), "myObject");
+         assertEquals(object.getEtag(), "8a964ee2a5e88be344f36c22562a6486");
+         assertEquals(object.getLastModified(), dates.rfc822DateParse("Fri, 12 Jun 2010 13:40:18 GMT"));
+         for (Entry<String, String> entry : object.getMetadata().entrySet()) {
+            assertEquals(object.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue());
          }
-         assertEquals(object.payload().getContentMetadata().getContentLength(), new Long(4));
-         assertEquals(object.payload().getContentMetadata().getContentType(), "text/plain; charset=UTF-8");
+         assertEquals(object.getPayload().getContentMetadata().getContentLength(), new Long(4));
+         assertEquals(object.getPayload().getContentMetadata().getContentType(), "text/plain; charset=UTF-8");
          // note MWS doesn't process Range header at the moment
-         assertEquals(Strings2.toStringAndClose(object.payload().getInput()), "ABCD");
+         assertEquals(Strings2.toStringAndClose(object.getPayload().getInput()), "ABCD");
 
          assertEquals(server.getRequestCount(), 2);
          assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
@@ -229,9 +213,9 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    public void updateMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
       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")));
+      server.enqueue(addCommonHeaders(objectResponse()
+            .addHeader(OBJECT_METADATA_PREFIX + "ApiName", "swift")
+            .addHeader(OBJECT_METADATA_PREFIX + "ApiVersion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -243,7 +227,7 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertEquals(replaceRequest.getRequestLine(),
                "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
          for (Entry<String, String> entry : metadata.entrySet()) {
-            assertEquals(replaceRequest.getHeader("x-object-meta-" + entry.getKey().toLowerCase()), entry.getValue());
+            assertEquals(replaceRequest.getHeader(OBJECT_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
          }
       } finally {
          server.shutdown();
@@ -265,7 +249,7 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertEquals(deleteRequest.getRequestLine(),
                "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject HTTP/1.1");
          for (String key : metadata.keySet()) {
-            assertEquals(deleteRequest.getHeader("x-remove-object-meta-" + key.toLowerCase()), "ignored");
+            assertEquals(deleteRequest.getHeader(OBJECT_REMOVE_METADATA_PREFIX + key.toLowerCase()), "ignored");
          }
       } finally {
          server.shutdown();
@@ -350,12 +334,12 @@ public class ObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
 
    public static MockResponse objectResponse() {
-      return new MockResponse() //
-            .addHeader("Last-Modified", "Fri, 12 Jun 2010 13:40:18 GMT") //
-            .addHeader("ETag", "8a964ee2a5e88be344f36c22562a6486") //
+      return new MockResponse()
+            .addHeader("Last-Modified", "Fri, 12 Jun 2010 13:40:18 GMT")
+            .addHeader("ETag", "8a964ee2a5e88be344f36c22562a6486")
             // TODO: MWS doesn't allow you to return content length w/o content
             // on HEAD!
-            .setBody("ABCD".getBytes(US_ASCII)) //
+            .setBody("ABCD".getBytes(US_ASCII))
             .addHeader("Content-Length", "4").addHeader("Content-Type", "text/plain; charset=UTF-8");
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 eb08f76..aa6f434 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
@@ -19,12 +19,12 @@ package org.jclouds.openstack.swift.v1.features;
 import static java.lang.String.format;
 import static org.jclouds.io.Payloads.newPayload;
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotEquals;
 import static org.testng.Assert.assertNotNull;
 
 import java.util.List;
 import java.util.UUID;
 
+import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.Segment;
 import org.jclouds.openstack.swift.v1.domain.SwiftObject;
 import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
@@ -37,20 +37,20 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
 @Test(groups = "live", testName = "StaticLargeObjectApiLiveTest")
-public class StaticLargeObjectApiLiveTest extends BaseSwiftApiLiveTest {
+public class StaticLargeObjectApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
 
    private String name = getClass().getSimpleName();
    private String containerName = getClass().getSimpleName() + "Container";
    private byte[] megOf1s;
    private byte[] megOf2s;
 
-   public void notPresentWhenDeleting() throws Exception {
+   public void testNotPresentWhenDeleting() throws Exception {
       for (String regionId : regions) {
          api.staticLargeObjectApiInRegionForContainer(regionId, containerName).delete(UUID.randomUUID().toString());
       }
    }
 
-   public void replaceManifest() throws Exception {
+   public void testReplaceManifest() throws Exception {
       for (String regionId : regions) {
          ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName);
          String etag1s = objectApi.replace(name + "/1", newPayload(megOf1s), ImmutableMap.<String, String> of());
@@ -74,23 +74,29 @@ public class StaticLargeObjectApiLiveTest extends BaseSwiftApiLiveTest {
          assertNotNull(etagOfEtags);
 
          SwiftObject bigObject = api.objectApiInRegionForContainer(regionId, containerName).head(name);
-         assertNotEquals(bigObject.etag(), etagOfEtags);
-         assertEquals(bigObject.payload().getContentMetadata().getContentLength(), new Long(2 * 1024 * 1024));
-         assertEquals(bigObject.metadata(), ImmutableMap.of("myfoo", "Bar"));
+         assertEquals(bigObject.getEtag(), etagOfEtags);
+         assertEquals(bigObject.getPayload().getContentMetadata().getContentLength(), new Long(2 * 1024 * 1024));
+         assertEquals(bigObject.getMetadata(), ImmutableMap.of("myfoo", "Bar"));
 
          // segments are visible
-         assertEquals(api.containerApiInRegion(regionId).get(containerName).objectCount(), 3);
+         assertEquals(api.containerApiInRegion(regionId).get(containerName).getObjectCount(), 3);
       }
    }
 
-   @Test(dependsOnMethods = "replaceManifest")
-   public void delete() throws Exception {
+   @Test(dependsOnMethods = "testReplaceManifest")
+   public void testDelete() throws Exception {
       for (String regionId : regions) {
          api.staticLargeObjectApiInRegionForContainer(regionId, containerName).delete(name);
-         assertEquals(api.containerApiInRegion(regionId).get(containerName).objectCount(), 0);
+         assertEquals(api.containerApiInRegion(regionId).get(containerName).getObjectCount(), 0);
       }
    }
 
+   protected void assertMegabyteAndETagMatches(String regionId, String name, String etag1s) {
+      SwiftObject object1s = api.objectApiInRegionForContainer(regionId, containerName).head(name);
+      assertEquals(object1s.getEtag(), etag1s);
+      assertEquals(object1s.getPayload().getContentMetadata().getContentLength(), new Long(1024 * 1024));
+   }
+
    @Override
    @BeforeClass(groups = "live")
    public void setup() {
@@ -119,10 +125,4 @@ public class StaticLargeObjectApiLiveTest extends BaseSwiftApiLiveTest {
       }
       super.tearDown();
    }
-
-   protected void assertMegabyteAndETagMatches(String regionId, String name, String etag1s) {
-      SwiftObject object1s = api.objectApiInRegionForContainer(regionId, containerName).head(name);
-      assertEquals(object1s.etag(), etag1s);
-      assertEquals(object1s.payload().getContentMetadata().getContentLength(), new Long(1024 * 1024));
-   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 4da10a9..a10c340 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
@@ -16,6 +16,7 @@
  */
 package org.jclouds.openstack.swift.v1.features;
 
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_METADATA_PREFIX;
 import static org.testng.Assert.assertEquals;
 
 import org.jclouds.openstack.swift.v1.SwiftApi;
@@ -30,10 +31,10 @@ import com.squareup.okhttp.mockwebserver.MockResponse;
 import com.squareup.okhttp.mockwebserver.MockWebServer;
 import com.squareup.okhttp.mockwebserver.RecordedRequest;
 
-@Test
+@Test(groups = "unit", testName = "StaticLargeObjectApiMockTest")
 public class StaticLargeObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
-   public void replaceManifest() throws Exception {
+   public void testReplaceManifest() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().addHeader(HttpHeaders.ETAG, "\"abcd\"")));
@@ -54,11 +55,11 @@ public class StaticLargeObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi
                      ImmutableMap.of("MyFoo", "Bar")), "abcd");
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+         assertAuthentication(server);
+
          RecordedRequest replaceRequest = server.takeRequest();
-         assertEquals(replaceRequest.getRequestLine(),
-               "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject?multipart-manifest=put HTTP/1.1");
-         assertEquals(replaceRequest.getHeader("x-object-meta-myfoo"), "Bar");
+         assertRequest(replaceRequest, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject?multipart-manifest=put");
+         assertEquals(replaceRequest.getHeader(OBJECT_METADATA_PREFIX + "myfoo"), "Bar");
          assertEquals(
                new String(replaceRequest.getBody()),
          "[{\"path\":\"/mycontainer/objseg1\",\"etag\":\"0228c7926b8b642dfb29554cd1f00963\",\"size_bytes\":1468006}," +
@@ -69,7 +70,7 @@ public class StaticLargeObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi
       }
    }
 
-   public void delete() throws Exception {
+   public void testDelete() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(204)));
@@ -79,16 +80,15 @@ public class StaticLargeObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi
          api.staticLargeObjectApiInRegionForContainer("DFW", "myContainer").delete("myObject");
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         RecordedRequest deleteRequest = server.takeRequest();
-         assertEquals(deleteRequest.getRequestLine(),
-               "DELETE /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject?multipart-manifest=delete HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "DELETE", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject?multipart-manifest=delete");
+      
       } finally {
          server.shutdown();
       }
    }
 
-   public void alreadyDeleted() throws Exception {
+   public void testAlreadyDeleted() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(404)));
@@ -98,10 +98,8 @@ public class StaticLargeObjectApiMockTest extends BaseOpenStackMockTest<SwiftApi
          api.staticLargeObjectApiInRegionForContainer("DFW", "myContainer").delete("myObject");
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         RecordedRequest deleteRequest = server.takeRequest();
-         assertEquals(deleteRequest.getRequestLine(),
-               "DELETE /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject?multipart-manifest=delete HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "DELETE", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer/myObject?multipart-manifest=delete");
       } finally {
          server.shutdown();
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/UrlEncodeAndJoinOnNewlineTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/UrlEncodeAndJoinOnNewlineTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/UrlEncodeAndJoinOnNewlineTest.java
index a45386b..c811571 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/UrlEncodeAndJoinOnNewlineTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/UrlEncodeAndJoinOnNewlineTest.java
@@ -24,7 +24,7 @@ import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
 
-@Test
+@Test(groups = "unit", testName = "UrlEncodeAndJoinOnNewlineTest")
 public class UrlEncodeAndJoinOnNewlineTest {
    UrlEncodeAndJoinOnNewline binder = new UrlEncodeAndJoinOnNewline();
 
@@ -38,8 +38,7 @@ public class UrlEncodeAndJoinOnNewlineTest {
             .add("/v1/12345678912345/mycontainer/home/xx<yy")
             .add("/v1/12345678912345/mycontainer/../image.gif").build());
 
-      assertEquals(request.getPayload().getRawContent(), "" //
-            + "/v1/12345678912345/mycontainer/home/xx%3Cyy\n" //
+      assertEquals(request.getPayload().getRawContent(), "/v1/12345678912345/mycontainer/home/xx%3Cyy\n"
             + "/v1/12345678912345/mycontainer/../image.gif");
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 239177c..6be7907 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
@@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkState;
 import java.util.List;
 import java.util.Properties;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 import org.jclouds.apis.BaseApiLiveTest;
 import org.jclouds.location.reference.LocationConstants;
@@ -31,19 +32,22 @@ 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 org.testng.annotations.Test;
 
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Uninterruptibles;
 
-public class BaseSwiftApiLiveTest extends BaseApiLiveTest<SwiftApi> {
+@Test(groups = "live", testName = "BaseSwiftApiLiveTest")
+public abstract class BaseSwiftApiLiveTest<A extends SwiftApi> extends BaseApiLiveTest<A> {
 
    protected Set<String> regions;
    
-   public BaseSwiftApiLiveTest() {
+   protected BaseSwiftApiLiveTest() {
       provider = "openstack-swift";
    }
-   
+
    @Override
    @BeforeClass(groups = "live")
    public void setup() {
@@ -55,7 +59,7 @@ public class BaseSwiftApiLiveTest extends BaseApiLiveTest<SwiftApi> {
         regions = api.configuredRegions();
       }
    }
-   
+
    @Override
    protected Properties setupProperties() {
       Properties props = super.setupProperties();
@@ -65,18 +69,20 @@ public class BaseSwiftApiLiveTest extends BaseApiLiveTest<SwiftApi> {
    }
 
    protected void deleteAllObjectsInContainer(String regionId, final String containerName) {
+      Uninterruptibles.sleepUninterruptibly(10, TimeUnit.SECONDS);
+      
       ObjectList objects = api.objectApiInRegionForContainer(regionId, containerName).list(new ListContainerOptions());
       if (objects == null) {
          return;
       }
       List<String> pathsToDelete = Lists.transform(objects, new Function<SwiftObject, String>() {
          public String apply(SwiftObject input) {
-            return containerName + "/" + input.name();
+            return containerName + "/" + input.getName();
          }
       });
       if (!pathsToDelete.isEmpty()) {
          BulkDeleteResponse response = api.bulkApiInRegion(regionId).bulkDelete(pathsToDelete);
-         checkState(response.errors().isEmpty(), "Errors deleting paths %s: %s", pathsToDelete, response);
+         checkState(response.getErrors().isEmpty(), "Errors deleting paths %s: %s", pathsToDelete, response);
       }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/resources/container_list.json
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/resources/container_list.json b/openstack-swift/src/test/resources/container_list.json
new file mode 100644
index 0000000..554f5de
--- /dev/null
+++ b/openstack-swift/src/test/resources/container_list.json
@@ -0,0 +1,12 @@
+[
+    {
+        "name": "test_container_1",
+        "count": 2,
+        "bytes": 78
+    },
+    {
+        "name": "test_container_2",
+        "count": 1,
+        "bytes": 17
+    }
+]

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/resources/object_list.json
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/resources/object_list.json b/openstack-swift/src/test/resources/object_list.json
new file mode 100644
index 0000000..9cac144
--- /dev/null
+++ b/openstack-swift/src/test/resources/object_list.json
@@ -0,0 +1,16 @@
+[
+    {
+        "name": "test_obj_1",
+        "hash": "4281c348eaf83e70ddce0e07221c3d28",
+        "bytes": 14,
+        "content_type": "application/octet-stream",
+        "last_modified": "2009-02-03T05:26:32.612278"
+    },
+    {
+        "name": "test_obj_2",
+        "hash": "b039efe731ad111bc1b0ef221c3849d0",
+        "bytes": 64,
+        "content_type": "application/octet-stream",
+        "last_modified": "2009-02-03T05:26:32.612278"
+    }
+]

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1f900d6..b888796 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,6 +63,8 @@
     <module>rackspace-cloudqueues-uk</module>
     <module>rackspace-cloudbigdata</module>
     <module>rackspace-cloudbigdata-us</module>
+    <module>rackspace-cloudfiles</module>
+    <module>rackspace-cloudfiles-us</module>
   </modules>
 
   <build>

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/README.md
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/README.md b/rackspace-cloudfiles-us/README.md
new file mode 100644
index 0000000..25ded8c
--- /dev/null
+++ b/rackspace-cloudfiles-us/README.md
@@ -0,0 +1,20 @@
+Rackspace Cloud Files US
+========================
+
+The new Rackspace Cloud Files US multi-region based provider.
+
+This new "rackspace-cloudfiles-us" provider supercedes the jclouds "cloudfiles-us" provider, which will eventually be deprecated.
+
+With this multi-region support, each BlobStore can be isolated to a specific region:
+
+     RegionScopedBlobStoreContext ctx = 
+     	contextBuilder.buildView(RegionScopedBlobStoreContext.class);
+ 
+     Set<String> regionIds = ctx.configuredRegions();
+ 
+     // isolated to a specific region
+     BlobStore dfwBlobStore = ctx.blobStoreInRegion("DFW");
+     BlobStore iadBlobStore = ctx.blobStoreInRegion("IAD");
+
+Production ready?
+No

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/pom.xml
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/pom.xml b/rackspace-cloudfiles-us/pom.xml
new file mode 100644
index 0000000..b882ed3
--- /dev/null
+++ b/rackspace-cloudfiles-us/pom.xml
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.jclouds</groupId>
+    <artifactId>jclouds-project</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+  </parent>
+
+  <!-- TODO: when out of labs, switch to org.jclouds.provider -->
+  <groupId>org.apache.jclouds.labs</groupId>
+  <artifactId>rackspace-cloudfiles-us</artifactId>
+  <version>1.8.0-SNAPSHOT</version>
+  <name>jclouds Rackspace Cloud Files US provider</name>
+  <description>OpenStack Object Storage implementation targeted to Rackspace Cloud Files US</description>
+  <packaging>bundle</packaging>
+
+  <properties>
+    <!-- identity endpoint -->
+    <test.rackspace-cloudfiles-us.endpoint>https://identity.api.rackspacecloud.com/v2.0/</test.rackspace-cloudfiles-us.endpoint>
+    <test.rackspace-cloudfiles-us.api-version>1</test.rackspace-cloudfiles-us.api-version>
+    <test.rackspace-cloudfiles-us.build-version />
+    <test.rackspace-cloudfiles-us.identity>${test.rackspace-us.identity}</test.rackspace-cloudfiles-us.identity>
+    <test.rackspace-cloudfiles-us.credential>${test.rackspace-us.credential}</test.rackspace-cloudfiles-us.credential>    
+    <jclouds.osgi.export>org.jclouds.rackspace.cloudfiles.us*;version="${project.version}"</jclouds.osgi.export>
+    <jclouds.osgi.import>
+      org.jclouds.rest.internal;version="${jclouds.version}",
+      org.jclouds.labs*;version="${project.version}",
+      org.jclouds*;version="${jclouds.version}",
+      *
+    </jclouds.osgi.import>
+  </properties>
+
+  <repositories>
+    <repository>
+      <id>apache-snapshots</id>
+      <url>https://repository.apache.org/content/repositories/snapshots</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.jclouds.labs</groupId>
+      <artifactId>openstack-swift</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.labs</groupId>
+      <artifactId>openstack-swift</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.labs</groupId>
+      <artifactId>rackspace-cloudfiles</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.labs</groupId>
+      <artifactId>rackspace-cloudfiles</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>    
+      <groupId>org.apache.jclouds.api</groupId>
+      <artifactId>openstack-keystone</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.api</groupId>
+      <artifactId>openstack-keystone</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds</groupId>
+      <artifactId>jclouds-blobstore</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds</groupId>
+      <artifactId>jclouds-core</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds</groupId>
+      <artifactId>jclouds-core</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.driver</groupId>
+      <artifactId>jclouds-slf4j</artifactId>
+      <version>${project.parent.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.jclouds.api</groupId>
+    	<artifactId>rackspace-cloudidentity</artifactId>
+    	<version>${project.parent.version}</version>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>live</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>integration</id>
+                <phase>integration-test</phase>
+                <goals>
+                  <goal>test</goal>
+                </goals>
+                <configuration>
+                  <forkCount>5</forkCount>
+                  <reuseForks>true</reuseForks>
+                  <parallel>classes</parallel>
+                  <systemPropertyVariables>
+                    <test.rackspace-cloudfiles-us.endpoint>${test.rackspace-cloudfiles-us.endpoint}</test.rackspace-cloudfiles-us.endpoint>
+                    <test.rackspace-cloudfiles-us.api-version>${test.rackspace-cloudfiles-us.api-version}</test.rackspace-cloudfiles-us.api-version>
+                    <test.rackspace-cloudfiles-us.build-version>${test.rackspace-cloudfiles-us.build-version}</test.rackspace-cloudfiles-us.build-version>
+                    <test.rackspace-cloudfiles-us.identity>${test.rackspace-cloudfiles-us.identity}</test.rackspace-cloudfiles-us.identity>
+                    <test.rackspace-cloudfiles-us.credential>${test.rackspace-cloudfiles-us.credential}</test.rackspace-cloudfiles-us.credential>
+                    <jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
+                    <jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
+                  </systemPropertyVariables>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+</project>

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderMetadata.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderMetadata.java b/rackspace-cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderMetadata.java
new file mode 100644
index 0000000..beb9521
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderMetadata.java
@@ -0,0 +1,145 @@
+/*
+ * 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.rackspace.cloudfiles.us;
+
+import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
+import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
+import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.reflect.Reflection2.typeToken;
+
+import java.net.URI;
+import java.util.Properties;
+
+import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.swift.v1.blobstore.RegionScopedBlobStoreContext;
+import org.jclouds.openstack.swift.v1.blobstore.config.SignUsingTemporaryUrls;
+import org.jclouds.openstack.swift.v1.blobstore.config.SwiftBlobStoreContextModule;
+import org.jclouds.openstack.swift.v1.config.SwiftTypeAdapters;
+import org.jclouds.openstack.v2_0.ServiceType;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.providers.internal.BaseProviderMetadata;
+import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApiMetadata;
+import org.jclouds.rackspace.cloudfiles.v1.config.CloudFilesHttpApiModule;
+import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
+import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
+import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+
+/**
+ * Implementation of {@link ProviderMetadata} for Rackspace Cloud Files US regions.
+ * 
+ * @author Jeremy Daggett
+ */
+public class CloudFilesUSProviderMetadata extends BaseProviderMetadata {
+   
+   /**
+    * @return The Builder object.
+    */
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   @Override
+   public Builder toBuilder() {
+      return builder().fromProviderMetadata(this);
+   }
+
+   /**
+    * Provider constructor.
+    */
+   public CloudFilesUSProviderMetadata() {
+      this(new Builder());
+   }
+
+   /**
+    * @param builder the Builder for the provider.
+    */
+   protected CloudFilesUSProviderMetadata(Builder builder) {
+      super(builder);
+   }
+
+   /**
+    * @return a {@link Properties} object containing the default provider properties.
+    */
+   public static Properties defaultProperties() {
+      Properties properties = new Properties();
+      properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
+      properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE); 
+
+      properties.setProperty(PROPERTY_REGIONS, "ORD,DFW,IAD,SYD,HKG");
+      properties.setProperty(PROPERTY_REGION + ".ORD." + ISO3166_CODES, "US-IL");
+      properties.setProperty(PROPERTY_REGION + ".DFW." + ISO3166_CODES, "US-TX");
+      properties.setProperty(PROPERTY_REGION + ".IAD." + ISO3166_CODES, "US-VA");
+      properties.setProperty(PROPERTY_REGION + ".SYD." + ISO3166_CODES, "AU-NSW");
+      properties.setProperty(PROPERTY_REGION + ".HKG." + ISO3166_CODES, "HK");
+
+      return properties;
+   }
+
+   /**
+    * Builder pattern class.
+    */
+   public static class Builder extends BaseProviderMetadata.Builder {
+
+      protected Builder() {
+         id("rackspace-cloudfiles-us")
+         .name("Rackspace Cloud Files US")
+         .apiMetadata(new CloudFilesApiMetadata().toBuilder()
+               .identityName("${userName}")
+               .credentialName("${apiKey}")
+               .defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/")
+               .documentation(URI.create("http://docs.rackspace.com/files/api/v1/cf-devguide/content/index.html"))
+               .endpointName("Rackspace Cloud Identity service URL ending in /v2.0/")
+               .version("1.0")
+               .view(typeToken(RegionScopedBlobStoreContext.class))
+               .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
+                     .add(CloudIdentityAuthenticationApiModule.class)
+                     .add(CloudIdentityAuthenticationModule.class)
+                     .add(RegionModule.class)
+                     .add(SwiftTypeAdapters.class)
+                     .add(CloudFilesHttpApiModule.class)
+                     .add(SwiftBlobStoreContextModule.class)
+                     .add(SignUsingTemporaryUrls.class)
+                     .build())
+               .build())
+         .homepage(URI.create("http://www.rackspace.com/cloud/files"))
+         .console(URI.create("https://mycloud.rackspace.com"))
+         .linkedServices("rackspace-autoscale-us", "rackspace-cloudblockstorage-us",
+                         "rackspace-clouddatabases-us", "rackspace-clouddns-us",
+                         "rackspace-cloudidentity", "rackspace-cloudloadbalancers-us",
+                         "rackspace-cloudqueues-us")
+         .iso3166Codes("US-IL", "US-TX", "US-VA", "AU-NSW", "HK")
+         .defaultProperties(CloudFilesUSProviderMetadata.defaultProperties());
+         
+      }
+
+      @Override
+      public CloudFilesUSProviderMetadata build() {
+         return new CloudFilesUSProviderMetadata(this);
+      }
+
+      @Override
+      public Builder fromProviderMetadata(ProviderMetadata in) {
+         super.fromProviderMetadata(in);
+         return this;
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata b/rackspace-cloudfiles-us/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata
new file mode 100644
index 0000000..cf4c3b4
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.jclouds.rackspace.cloudfiles.us.CloudFilesUSProviderMetadata

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderTest.java b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderTest.java
new file mode 100644
index 0000000..05d036a
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderTest.java
@@ -0,0 +1,29 @@
+/*
+ * 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.rackspace.cloudfiles.us;
+
+import org.jclouds.providers.internal.BaseProviderMetadataTest;
+import org.jclouds.rackspace.cloudfiles.us.CloudFilesUSProviderMetadata;
+import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApiMetadata;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "CloudFilesUSProviderTest")
+public class CloudFilesUSProviderTest extends BaseProviderMetadataTest {
+   public CloudFilesUSProviderTest() {
+      super(new CloudFilesUSProviderMetadata(), new CloudFilesApiMetadata());
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobIntegrationLiveTest.java b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobIntegrationLiveTest.java
new file mode 100644
index 0000000..b684e89
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobIntegrationLiveTest.java
@@ -0,0 +1,27 @@
+/*
+ * 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.rackspace.cloudfiles.us.blobstore.integration;
+
+import org.jclouds.rackspace.cloudfiles.v1.blobstore.integration.CloudFilesBlobIntegrationLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesUSBlobIntegrationLiveTest")
+public class CloudFilesUSBlobIntegrationLiveTest extends CloudFilesBlobIntegrationLiveTest {
+   public CloudFilesUSBlobIntegrationLiveTest() {
+      provider = "rackspace-cloudfiles-us";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobLiveTest.java b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobLiveTest.java
new file mode 100644
index 0000000..8eb5385
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobLiveTest.java
@@ -0,0 +1,27 @@
+/*
+ * 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.rackspace.cloudfiles.us.blobstore.integration;
+
+import org.jclouds.rackspace.cloudfiles.v1.blobstore.integration.CloudFilesBlobLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesUSBlobLiveTest")
+public class CloudFilesUSBlobLiveTest extends CloudFilesBlobLiveTest {
+   public CloudFilesUSBlobLiveTest() {
+      provider = "rackspace-cloudfiles-us";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobSignerLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobSignerLiveTest.java b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobSignerLiveTest.java
new file mode 100644
index 0000000..5255de2
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSBlobSignerLiveTest.java
@@ -0,0 +1,27 @@
+/*
+ * 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.rackspace.cloudfiles.us.blobstore.integration;
+
+import org.jclouds.rackspace.cloudfiles.v1.blobstore.integration.CloudFilesBlobSignerLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesUSBlobSignerLiveTest")
+public class CloudFilesUSBlobSignerLiveTest extends CloudFilesBlobSignerLiveTest {
+   public CloudFilesUSBlobSignerLiveTest() {
+      provider = "rackspace-cloudfiles-us";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSContainerIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSContainerIntegrationLiveTest.java b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSContainerIntegrationLiveTest.java
new file mode 100644
index 0000000..2fe511e
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSContainerIntegrationLiveTest.java
@@ -0,0 +1,27 @@
+/*
+ * 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.rackspace.cloudfiles.us.blobstore.integration;
+
+import org.jclouds.rackspace.cloudfiles.v1.blobstore.integration.CloudFilesContainerIntegrationLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesUSContainerIntegrationLiveTest")
+public class CloudFilesUSContainerIntegrationLiveTest extends CloudFilesContainerIntegrationLiveTest {
+   public CloudFilesUSContainerIntegrationLiveTest() {
+      provider = "rackspace-cloudfiles-us";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSContainerLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSContainerLiveTest.java b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSContainerLiveTest.java
new file mode 100644
index 0000000..44daffd
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSContainerLiveTest.java
@@ -0,0 +1,27 @@
+/*
+ * 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.rackspace.cloudfiles.us.blobstore.integration;
+
+import org.jclouds.rackspace.cloudfiles.v1.blobstore.integration.CloudFilesContainerLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesUSContainerLiveTest")
+public class CloudFilesUSContainerLiveTest extends CloudFilesContainerLiveTest {
+   public CloudFilesUSContainerLiveTest() {
+      provider = "rackspace-cloudfiles-us";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSServiceIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSServiceIntegrationLiveTest.java b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSServiceIntegrationLiveTest.java
new file mode 100644
index 0000000..698b733
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/us/blobstore/integration/CloudFilesUSServiceIntegrationLiveTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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.rackspace.cloudfiles.us.blobstore.integration;
+
+import java.util.Set;
+
+import org.jclouds.rackspace.cloudfiles.v1.blobstore.integration.CloudFilesServiceIntegrationLiveTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+@Test(groups = "live", testName = "CloudFilesUSServiceIntegrationLiveTest")
+public class CloudFilesUSServiceIntegrationLiveTest extends CloudFilesServiceIntegrationLiveTest {
+   public CloudFilesUSServiceIntegrationLiveTest() {
+      provider = "rackspace-cloudfiles-us";
+   }
+
+   @Override
+   protected Set<String> getIso3166Codes() {
+      return ImmutableSet.<String> of("US-IL", "US-TX", "US-VA", "AU-NSW", "HK");
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles-us/src/test/resources/logback.xml
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles-us/src/test/resources/logback.xml b/rackspace-cloudfiles-us/src/test/resources/logback.xml
new file mode 100644
index 0000000..ce891f1
--- /dev/null
+++ b/rackspace-cloudfiles-us/src/test/resources/logback.xml
@@ -0,0 +1,71 @@
+<?xml version="1.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.
+
+-->
+<configuration scan="false">
+    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+        <file>target/test-data/jclouds.log</file>
+
+        <encoder>
+            <Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
+        </encoder>
+    </appender>
+
+    <appender name="WIREFILE" class="ch.qos.logback.core.FileAppender">
+        <file>target/test-data/jclouds-wire.log</file>
+
+        <encoder>
+            <Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
+        </encoder>
+    </appender>
+
+    <appender name="BLOBSTOREFILE" class="ch.qos.logback.core.FileAppender">
+        <file>target/test-data/jclouds-blobstore.log</file>
+
+        <encoder>
+            <Pattern>%d %-5p [%c] [%thread] %m%n</Pattern>
+        </encoder>
+    </appender>
+    
+    <root>
+        <level value="warn" />
+    </root>
+
+    <logger name="org.jclouds">
+        <level value="DEBUG" />
+        <appender-ref ref="FILE" />
+    </logger>
+
+<!--
+    <logger name="jclouds.wire">
+        <level value="DEBUG" />
+        <appender-ref ref="WIREFILE" />
+    </logger>
+-->
+
+    <logger name="jclouds.headers">
+        <level value="DEBUG" />
+        <appender-ref ref="WIREFILE" />
+    </logger>
+
+    <logger name="jclouds.blobstore">
+        <level value="DEBUG" />
+        <appender-ref ref="BLOBSTOREFILE" />
+    </logger>
+
+</configuration>

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/README.md
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/README.md b/rackspace-cloudfiles/README.md
new file mode 100644
index 0000000..1142323
--- /dev/null
+++ b/rackspace-cloudfiles/README.md
@@ -0,0 +1,20 @@
+Rackspace Cloud Files
+==========================
+
+The new Rackspace Cloud Files multi-region based service API.
+
+This new "rackspace-cloudfiles" API supercedes the jclouds "cloudfiles" API, which will eventually be deprecated.
+
+With this multi-region support, each BlobStore can be isolated to a specific region:
+
+     RegionScopedBlobStoreContext ctx = 
+     	contextBuilder.buildView(RegionScopedBlobStoreContext.class);
+ 
+     Set<String> regionIds = ctx.configuredRegions();
+ 
+     // isolated to a specific region
+     BlobStore dfwBlobStore = ctx.blobStoreInRegion("DFW");
+     BlobStore iadBlobStore = ctx.blobStoreInRegion("IAD");
+
+Production ready?
+No


[2/5] JCLOUDS-423 - Adds support for Rackspace Cloud Files API - Added support for CloudFilesApi/CDNApi - Added mock/live tests - Refactored listFirstPage() and listAt() API methods to list() and listWithOptions(…) - General Swift API cleanup: docs and t

Posted by za...@apache.org.
http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/pom.xml
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/pom.xml b/rackspace-cloudfiles/pom.xml
new file mode 100644
index 0000000..59662c9
--- /dev/null
+++ b/rackspace-cloudfiles/pom.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.jclouds</groupId>
+    <artifactId>jclouds-project</artifactId>
+    <version>1.8.0-SNAPSHOT</version>
+  </parent>
+
+  <!-- TODO: when out of labs, switch to org.jclouds.api -->
+  <groupId>org.apache.jclouds.labs</groupId>
+  <artifactId>rackspace-cloudfiles</artifactId>
+  <version>1.8.0-SNAPSHOT</version>
+  <name>jclouds rackspace-cloudfiles api</name>
+  <description>jclouds components to access Rackspace Cloud Files</description>
+  <packaging>bundle</packaging>
+
+  <properties>
+    <!-- identity endpoint -->
+    <test.rackspace-cloudfiles.endpoint>https://identity.api.rackspacecloud.com/v2.0/</test.rackspace-cloudfiles.endpoint>
+    <test.rackspace-cloudfiles.api-version>1</test.rackspace-cloudfiles.api-version>
+    <test.rackspace-cloudfiles.build-version />
+    <test.rackspace-cloudfiles.identity>FIXME_IDENTITY</test.rackspace-cloudfiles.identity>
+    <test.rackspace-cloudfiles.credential>FIXME_CREDENTIALS</test.rackspace-cloudfiles.credential>
+    <jclouds.osgi.export>org.jclouds.rackspace.cloudfiles.v1*;version="${project.version}"</jclouds.osgi.export>
+    <jclouds.osgi.import>org.jclouds*;version="${jclouds.version}",*</jclouds.osgi.import>
+  </properties>
+
+  <repositories>
+    <repository>
+      <id>apache-snapshots</id>
+      <url>https://repository.apache.org/content/repositories/snapshots</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.jclouds.labs</groupId>
+      <artifactId>openstack-swift</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.labs</groupId>
+      <artifactId>openstack-swift</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.api</groupId>
+      <artifactId>openstack-keystone</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.api</groupId>
+      <artifactId>openstack-keystone</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.api</groupId>
+      <artifactId>rackspace-cloudidentity</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds</groupId>
+      <artifactId>jclouds-core</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds</groupId>
+      <artifactId>jclouds-core</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds</groupId>
+      <artifactId>jclouds-blobstore</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.shrinkwrap</groupId>
+      <artifactId>shrinkwrap-depchain</artifactId>
+      <version>1.2.0</version>
+      <type>pom</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.driver</groupId>
+      <artifactId>jclouds-slf4j</artifactId>
+      <version>${project.parent.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.squareup.okhttp</groupId>
+      <artifactId>mockwebserver</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>live</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>integration</id>
+                <phase>integration-test</phase>
+                <goals>
+                  <goal>test</goal>
+                </goals>
+                <configuration>
+                  <forkCount>5</forkCount>
+                  <reuseForks>true</reuseForks>
+                  <parallel>classes</parallel>
+                  <systemPropertyVariables>
+                    <test.rackspace-cloudfiles.endpoint>${test.rackspace-cloudfiles.endpoint}</test.rackspace-cloudfiles.endpoint>
+                    <test.rackspace-cloudfiles.api-version>${test.rackspace-cloudfiles.api-version}</test.rackspace-cloudfiles.api-version>
+                    <test.rackspace-cloudfiles.build-version>${test.rackspace-cloudfiles.build-version}</test.rackspace-cloudfiles.build-version>
+                    <test.rackspace-cloudfiles.identity>${test.rackspace-cloudfiles.identity}</test.rackspace-cloudfiles.identity>
+                    <test.rackspace-cloudfiles.credential>${test.rackspace-cloudfiles.credential}</test.rackspace-cloudfiles.credential>
+                    <jclouds.blobstore.httpstream.url>${jclouds.blobstore.httpstream.url}</jclouds.blobstore.httpstream.url>
+                    <jclouds.blobstore.httpstream.md5>${jclouds.blobstore.httpstream.md5}</jclouds.blobstore.httpstream.md5>
+                  </systemPropertyVariables>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+</project>

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApi.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApi.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApi.java
new file mode 100644
index 0000000..19667d7
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApi.java
@@ -0,0 +1,50 @@
+/*
+ * 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.rackspace.cloudfiles.v1;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.rackspace.cloudfiles.v1.features.CDNApi;
+import org.jclouds.rackspace.cloudfiles.v1.functions.RegionToCDNEndpoint;
+import org.jclouds.rest.annotations.Delegate;
+import org.jclouds.rest.annotations.EndpointParam;
+
+/**
+ * Rackspace Cloud Files is an affordable, redundant, scalable, and dynamic storage service
+ * offering. The core storage system is designed to provide a secure, network-accessible way to
+ * store an unlimited number of files. Each file can be as large as 5 gigabytes.
+ * <p/>
+ * Additionally, Cloud Files provides a simple yet powerful way to publish and distribute content
+ * behind a Content Distribution Network.
+ * 
+ * @author Jeremy Daggett
+ * 
+ * @see CDNApi
+ * @see SwiftApi
+ */
+public interface CloudFilesApi extends SwiftApi {
+
+   /**
+    * Provides access to Cloud Files CDN features.
+    * 
+    * @param region  the region to access the CDN API.
+    * 
+    * @return the {@link CDNApi} for the specified region.
+    */
+   @Delegate
+   CDNApi cdnApiInRegion(@EndpointParam(parser = RegionToCDNEndpoint.class) @Nullable String region);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadata.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadata.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadata.java
new file mode 100644
index 0000000..d28b40f
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadata.java
@@ -0,0 +1,104 @@
+/*
+ * 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.rackspace.cloudfiles.v1;
+
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.reflect.Reflection2.typeToken;
+
+import java.net.URI;
+import java.util.Properties;
+
+import org.jclouds.apis.ApiMetadata;
+import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.swift.v1.SwiftApiMetadata;
+import org.jclouds.openstack.swift.v1.blobstore.RegionScopedBlobStoreContext;
+import org.jclouds.openstack.swift.v1.blobstore.config.SignUsingTemporaryUrls;
+import org.jclouds.openstack.swift.v1.blobstore.config.SwiftBlobStoreContextModule;
+import org.jclouds.openstack.swift.v1.config.SwiftTypeAdapters;
+import org.jclouds.openstack.v2_0.ServiceType;
+import org.jclouds.rackspace.cloudfiles.v1.config.CloudFilesHttpApiModule;
+import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
+import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
+import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
+import org.jclouds.rest.internal.BaseHttpApiMetadata;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+
+/**
+ * Implementation of {@link ApiMetadata} for Cloud Files.
+ * 
+ * @author Jeremy Daggett
+ */
+public class CloudFilesApiMetadata extends BaseHttpApiMetadata<CloudFilesApi> {
+
+   @Override
+   public Builder toBuilder() {
+      return new Builder().fromApiMetadata(this);
+   }
+
+   public CloudFilesApiMetadata() {
+      this(new Builder());
+   }
+
+   protected CloudFilesApiMetadata(Builder builder) {
+      super(builder);
+   }
+
+   public static Properties defaultProperties() {
+      Properties properties = SwiftApiMetadata.defaultProperties();
+      properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
+      properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE);
+      return properties;
+   }
+
+   public static class Builder extends BaseHttpApiMetadata.Builder<CloudFilesApi, Builder> {
+
+      protected Builder() {
+          id("rackspace-cloudfiles")
+         .name("Rackspace Cloud Files API")
+         .identityName("${userName}")
+         .credentialName("${apiKey}")
+         .documentation(URI.create("http://docs.rackspace.com/files/api/v1/cf-devguide/content/index.html"))
+         .version("1.0")
+         .endpointName("Rackspace Cloud Identity service URL ending in /v2.0/")
+         .defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/")
+         .defaultProperties(CloudFilesApiMetadata.defaultProperties())
+         .view(typeToken(RegionScopedBlobStoreContext.class))
+         .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
+                                     .add(CloudIdentityAuthenticationApiModule.class)
+                                     .add(CloudIdentityAuthenticationModule.class)
+                                     .add(RegionModule.class)
+                                     .add(SwiftTypeAdapters.class)
+                                     .add(CloudFilesHttpApiModule.class)
+                                     .add(SwiftBlobStoreContextModule.class)
+                                     .add(SignUsingTemporaryUrls.class)
+                                     .build());
+      }
+
+      @Override
+      public CloudFilesApiMetadata build() {
+         return new CloudFilesApiMetadata(this);
+      }
+
+      @Override
+      protected Builder self() {
+         return this;
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/binders/BindCDNPurgeEmailAddressesToHeaders.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/binders/BindCDNPurgeEmailAddressesToHeaders.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/binders/BindCDNPurgeEmailAddressesToHeaders.java
new file mode 100644
index 0000000..c23f068
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/binders/BindCDNPurgeEmailAddressesToHeaders.java
@@ -0,0 +1,56 @@
+/*
+ * 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.rackspace.cloudfiles.v1.binders;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import javax.inject.Singleton;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rackspace.cloudfiles.v1.features.CDNApi;
+import org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders;
+import org.jclouds.rest.Binder;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMultimap;
+
+/**
+ * Binds a list of email addresses to request headers. 
+ * 
+ * @see {@link CDNApi#purgeObject(String, String, Iterable)}
+ * 
+ * @author Jeremy Daggett
+ */
+@Singleton
+public class BindCDNPurgeEmailAddressesToHeaders implements Binder {
+   @SuppressWarnings("unchecked")
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+      checkArgument(checkNotNull(input, "input") instanceof Iterable<?>, "this binder is only valid for Iterable!");
+      checkNotNull(request, "request");
+
+      Iterable<String> emails = (Iterable<String>) input;
+      String emailCSV = Joiner.on(", ").join((List<String>) emails);
+      ImmutableMultimap<String, String> headers = 
+            ImmutableMultimap.<String, String> of(CloudFilesHeaders.CDN_PURGE_OBJECT_EMAIL, emailCSV);
+      
+      return (R) request.toBuilder().replaceHeaders(headers).build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/config/CloudFilesHttpApiModule.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/config/CloudFilesHttpApiModule.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/config/CloudFilesHttpApiModule.java
new file mode 100644
index 0000000..092fec9
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/config/CloudFilesHttpApiModule.java
@@ -0,0 +1,50 @@
+/*
+ * 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.rackspace.cloudfiles.v1.config;
+
+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.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.config.BaseSwiftHttpApiModule;
+import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApi;
+import org.jclouds.rackspace.cloudfiles.v1.handlers.CloudFilesErrorHandler;
+import org.jclouds.rest.ConfiguresHttpApi;
+
+import com.google.inject.Scopes;
+
+@ConfiguresHttpApi
+public class CloudFilesHttpApiModule extends BaseSwiftHttpApiModule<CloudFilesApi> {
+
+   public CloudFilesHttpApiModule() {
+      super(CloudFilesApi.class);
+   }
+
+   @Override
+   protected void configure() {
+      super.configure();
+      bind(SwiftApi.class).to(CloudFilesApi.class).in(Scopes.SINGLETON);
+   }
+   
+   @Override
+   protected void bindErrorHandlers() {
+      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(CloudFilesErrorHandler.class);
+      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(CloudFilesErrorHandler.class);
+      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(CloudFilesErrorHandler.class);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/domain/CDNContainer.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/domain/CDNContainer.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/domain/CDNContainer.java
new file mode 100644
index 0000000..590bccb
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/domain/CDNContainer.java
@@ -0,0 +1,264 @@
+/*
+ * 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.rackspace.cloudfiles.v1.domain;
+
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.beans.ConstructorProperties;
+import java.net.URI;
+
+import javax.inject.Named;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+
+/**
+ * Represents a CDN Container in Rackspace Cloud Files.
+ * 
+ * @author Jeremy Daggett
+ */
+public class CDNContainer implements Comparable<CDNContainer> {
+
+   private String name;
+   @Named("cdn_enabled")
+   private boolean enabled;
+   @Named("log_retention")
+   private boolean logRetention;
+   private int ttl;
+   @Named("cdn_uri")
+   private URI uri;
+   @Named("cdn_ssl_uri")
+   private URI sslUri;
+   @Named("cdn_streaming_uri")
+   private URI streamingUri;
+   @Named("cdn_ios_uri")
+   private URI iosUri;
+
+   @ConstructorProperties({ "name", "cdn_enabled", "log_retention", "ttl", "cdn_uri", "cdn_ssl_uri", "cdn_streaming_uri", "cdn_ios_uri"})
+   public CDNContainer(String name, boolean enabled, boolean logRetention, int ttl, URI uri, URI sslUri, URI streamingUri, URI iosUri) {
+      this.name = checkNotNull(name, "name required");
+      this.enabled = enabled;
+      this.logRetention = logRetention;
+      this.ttl = ttl;
+      this.uri = checkNotNull(uri, "uri required");
+      this.sslUri = checkNotNull(sslUri, "sslUri required");
+      this.streamingUri = checkNotNull(streamingUri, "streamingUri required");
+      this.iosUri = checkNotNull(iosUri, "iosUri required");
+   }
+
+   /**
+    * <h3>NOTE</h3>
+    * The container name is not available from HEAD CDN responses and will be null.
+    *
+    * @return The name of this CDN container.
+    */
+   public String getName() {
+      return name;
+   }
+
+   /**
+    * @return {@code true} if the container is CDN enabled, {@code false} if not.
+    */
+   public boolean isEnabled() {
+      return enabled;
+   }
+
+   /**
+    * @return {@code true} if the logs will be retained for this CDN container, {@code false} if not.
+    */
+   public boolean isLogRetentionEnabled() {
+      return logRetention;
+   }
+
+   /**
+    * @return the TTL for this CDN container.
+    */
+   public int getTtl() {
+      return ttl;
+   }
+
+   /**
+    * @return the {@link URI} for this CDN container.
+    */
+   public URI getUri() {
+      return uri;
+   }
+
+   /**
+    * @return the SSL {@link URI} for this CDN container.
+    */
+   public URI getSslUri() {
+      return sslUri;
+   }
+
+   /**
+    * @return the streaming {@link URI} for this CDN container.
+    */
+   public URI getStreamingUri() {
+      return streamingUri;
+   }
+
+   /**
+    * @return the iOS {@link URI} for this CDN container.
+    */
+   public URI getIosUri() {
+      return iosUri;
+   }
+   
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      CDNContainer that = CDNContainer.class.cast(obj);
+      return Objects.equal(this.name, that.name)
+               && Objects.equal(this.enabled, that.enabled)
+               && Objects.equal(this.logRetention, that.logRetention)
+               && Objects.equal(this.ttl, that.ttl)
+               && Objects.equal(this.uri, that.uri)
+               && Objects.equal(this.sslUri, that.sslUri)
+               && Objects.equal(this.streamingUri, that.streamingUri)
+               && Objects.equal(this.iosUri, that.iosUri);
+   }
+   
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(getName(), isEnabled(), isLogRetentionEnabled(), getTtl(), getUri(), getSslUri(), getStreamingUri(), getIosUri());
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   protected ToStringHelper string() {
+      return toStringHelper("").omitNullValues()
+            .add("name", getName())
+            .add("enabled", isEnabled())
+            .add("logRetention", isLogRetentionEnabled())
+            .add("ttl", getTtl())
+            .add("uri", getUri())
+            .add("sslUri", getSslUri())
+            .add("streamingUri", getStreamingUri())
+            .add("iosUri", getIosUri());
+   }
+
+   @Override
+   public int compareTo(CDNContainer that) {
+      if (that == null)
+         return 1;
+      if (this == that)
+         return 0;
+      return this.getName().compareTo(that.getName());
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public static class Builder {
+      
+      private String name;
+      private boolean enabled;
+      private boolean logRetention;
+      private int ttl;
+      private URI uri;
+      private URI sslUri;
+      private URI streamingUri;
+      private URI iosUri;
+      
+      /**
+       * @see CDNContainer#getName()
+       */
+      public Builder name(String name) {
+         this.name = checkNotNull(name, "name");
+         return this;
+      }
+
+      /**
+       * @see CDNContainer#isEnabled()
+       */
+      public Builder enabled(boolean enabled) {
+         this.enabled = enabled;
+         return this;
+      }
+
+      /**
+       * @see CDNContainer#isLogRetentionEnabled()
+       */
+      public Builder logRetention(boolean logRetention) {
+         this.logRetention = logRetention;
+         return this;
+      }
+
+      /**
+       * @see CDNContainer#getTtl()
+       */
+      public Builder ttl(int ttl) {
+         this.ttl = ttl;
+         return this;
+      }
+
+      /**
+       * @see CDNContainer#getUri()
+       */
+      public Builder uri(URI uri) {
+         this.uri = uri;
+         return this;
+      }
+
+      /**
+       * @see CDNContainer#getSslUri()
+       */
+      public Builder sslUri(URI sslUri) {
+         this.sslUri = sslUri;
+         return this;
+      }
+
+      /**
+       * @see CDNContainer#getStreamingUri()
+       */
+      public Builder streamingUri(URI streamingUri) {
+         this.streamingUri = streamingUri;
+         return this;
+      }
+
+      /**
+       * @see CDNContainer#getIosUri()
+       */
+      public Builder iosUri(URI iosUri) {
+         this.iosUri = iosUri;
+         return this;
+      }
+
+      public CDNContainer build() {
+         return new CDNContainer(name, enabled, logRetention, ttl, uri, sslUri, streamingUri, iosUri);
+      }
+
+      public Builder fromContainer(CDNContainer from) {
+         return name(from.getName())
+               .enabled(from.isEnabled())
+               .logRetention(from.isLogRetentionEnabled())
+               .ttl(from.getTtl())
+               .uri(from.getUri())
+               .sslUri(from.getSslUri())
+               .streamingUri(from.getStreamingUri())
+               .iosUri(from.getIosUri());
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/features/CDNApi.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/features/CDNApi.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/features/CDNApi.java
new file mode 100644
index 0000000..326b951
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/features/CDNApi.java
@@ -0,0 +1,205 @@
+/*
+ * 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.rackspace.cloudfiles.v1.features;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_ENABLED;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_TTL;
+
+import java.io.Closeable;
+import java.net.URI;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApi;
+import org.jclouds.rackspace.cloudfiles.v1.binders.BindCDNPurgeEmailAddressesToHeaders;
+import org.jclouds.rackspace.cloudfiles.v1.domain.CDNContainer;
+import org.jclouds.rackspace.cloudfiles.v1.functions.ParseCDNContainerFromHeaders;
+import org.jclouds.rackspace.cloudfiles.v1.functions.ParseCDNContainerURIFromHeaders;
+import org.jclouds.rackspace.cloudfiles.v1.options.UpdateCDNContainerOptions;
+import org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders;
+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;
+
+import com.google.common.collect.FluentIterable;
+/**
+ * Provides access to the Rackspace Cloud Files CDN API features.
+ *
+ * <h3>NOTE</h3>
+ * Before a container can be CDN enabled, it must exist in the storage system. 
+ * To CDN enable the container, perform PUT request against it using the <code>publicURL</code> 
+ * noted in the service catalog for Cloud Files during Authentication and set the 
+ * <code>X-CDN-Enabled</code> header to <code>true</code>.
+ * 
+ * @author Jeremy Daggett
+ * 
+ * @see {@link CloudFilesApi#cdnApiInRegion(String)}
+ */
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(APPLICATION_JSON)
+public interface CDNApi extends Closeable {
+
+   /**
+    * Lists up to 10,000 CDN containers.
+    * 
+    * @return a list of CDN enabled containers ordered by name.
+    */
+   @Named("cdn:list")
+   @GET
+   @QueryParams(keys = {"format", "enabled_only"}, values = {"json", "true"})
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   @Path("/")
+   FluentIterable<CDNContainer> list();
+   
+   /**
+    * Lists CDN containers, with the given options.
+    * 
+    * @param options
+    *           the options to control output.
+    * 
+    * @return a list of CDN enabled containers ordered by name.
+    */
+   @Named("cdn:list")
+   @GET
+   @QueryParams(keys = {"format", "enabled_only"}, values = {"json", "true"})
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   @Path("/")
+   FluentIterable<CDNContainer> list(ListContainerOptions options);
+
+   /**
+    * Gets the specified CDN Container.
+    * 
+    * @param containerName
+    *           the name of the CDN Container
+    * 
+    * @return the CDNContainer or null, if not found.
+    */
+   @Named("cdn:get")
+   @HEAD
+   @ResponseParser(ParseCDNContainerFromHeaders.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Path("/{container}")
+   @Nullable
+   CDNContainer get(@PathParam("container") String containerName);
+
+   /**
+    * Enables the {@link CDNContainer}.
+    * 
+    * @param containerName
+    *           corresponds to {@link CDNContainer#getName()}.
+    *           
+    * @return the CDN container {@link URI} or {@code null}, if not found.
+    */
+   @Named("cdn:enable")
+   @PUT
+   @ResponseParser(ParseCDNContainerURIFromHeaders.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Path("/{containerName}")
+   @Headers(keys = CDN_ENABLED, values = "true")
+   @Nullable
+   URI enable(@PathParam("containerName") String containerName);
+
+   /**
+    * Enables the {@link CDNContainer} with a TTL.
+    * 
+    * @param containerName
+    *           corresponds to {@link CDNContainer#name()}.
+    * @param ttl
+    *           the TTL for the CDN Container.
+    *           
+    * @return the CDN container {@link URI} or {@code null}, if not found.
+    */
+   @Named("cdn:enable")
+   @PUT
+   @ResponseParser(ParseCDNContainerURIFromHeaders.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Path("/{containerName}")
+   @Headers(keys = CDN_ENABLED, values = "true")
+   @Nullable
+   URI enable(@PathParam("containerName") String containerName, 
+         @HeaderParam(CDN_TTL) int ttl);
+
+   /**
+    * Disables the {@link CDNContainer}.
+    * 
+    * @param containerName
+    *           corresponds to {@link CDNContainer#name()}.
+    *           
+    * @return {@code true} if the container was disabled, {@code false} if not.
+    */
+   @Named("cdn:disable")
+   @PUT
+   @Fallback(FalseOnNotFoundOr404.class)
+   @Path("/{containerName}")
+   @Headers(keys = CDN_ENABLED, values = "False")
+   boolean disable(@PathParam("containerName") String containerName);
+
+   /**
+    * Purges an object from the CDN.
+    * 
+    * @param containerName
+    *           corresponds to {@link CDNContainer#name()}.
+    * @param objectName
+    *           the object in the {@link CDNContainer} to purge.
+    * @param emails
+    *           the email addresses to notify after purging.
+    * 
+    * @return {@code true} if the object was successfully purged, {@code false} if not.
+    */
+   @Named("cdn:purge")
+   @DELETE
+   @Fallback(FalseOnNotFoundOr404.class)
+   @Path("/{containerName}/{objectName}")
+   @Headers(keys = CloudFilesHeaders.CDN_PURGE_OBJECT_EMAIL, values = "{email}")
+   boolean purgeObject(@PathParam("containerName") String containerName, 
+         @PathParam("objectName") String objectName, 
+         @BinderParam(BindCDNPurgeEmailAddressesToHeaders.class) Iterable<String> emails);
+
+   /**
+    * Updates a CDN container with the supplied {@link UpdateCDNContainerOptions} options.
+    * 
+    * @param containerName
+    *           corresponds to {@link CDNContainer#name()}.
+    *           
+    * @param options
+    *           the {@link UpdateCDNContainerOptions} options.
+    */
+   @Named("cdn:update")
+   @POST
+   @Fallback(FalseOnNotFoundOr404.class)
+   @Path("/{containerName}")
+   boolean update(@PathParam("containerName") String containerName, UpdateCDNContainerOptions options);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/ParseCDNContainerFromHeaders.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/ParseCDNContainerFromHeaders.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/ParseCDNContainerFromHeaders.java
new file mode 100644
index 0000000..e551ab1
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/ParseCDNContainerFromHeaders.java
@@ -0,0 +1,84 @@
+/*
+ * 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.rackspace.cloudfiles.v1.functions;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Lists.newArrayList;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_ENABLED;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_IOS_URI;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_LOG_RETENTION;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_SSL_URI;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_STREAMING_URI;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_TTL;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_URI;
+
+import java.net.URI;
+import java.util.List;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.rackspace.cloudfiles.v1.domain.CDNContainer;
+import org.jclouds.rest.InvocationContext;
+
+import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+
+/**
+ * Parses the {@link CDNContainer} from the response headers.
+ * 
+ * @author Jeremy Daggett
+ *
+ */
+public class ParseCDNContainerFromHeaders implements Function<HttpResponse, CDNContainer>,
+      InvocationContext<ParseCDNContainerFromHeaders> {
+
+   private HttpRequest request;
+
+   /**
+    * parses the http response headers to create a new {@link CDNContainer} object.
+    */
+   public CDNContainer apply(final HttpResponse from) {
+      String uri = checkNotNull(from.getFirstHeaderOrNull(CDN_URI), CDN_URI);
+      String sslUri = checkNotNull(from.getFirstHeaderOrNull(CDN_SSL_URI), CDN_SSL_URI);
+      String streamingUri = checkNotNull(from.getFirstHeaderOrNull(CDN_STREAMING_URI), CDN_STREAMING_URI);
+      String iosUri = checkNotNull(from.getFirstHeaderOrNull(CDN_IOS_URI), CDN_IOS_URI);
+      String enabled = checkNotNull(from.getFirstHeaderOrNull(CDN_ENABLED), CDN_ENABLED);
+      String logRetention = checkNotNull(from.getFirstHeaderOrNull(CDN_LOG_RETENTION), CDN_LOG_RETENTION);
+      String ttl = checkNotNull(from.getFirstHeaderOrNull(CDN_TTL), CDN_TTL);
+      
+      // just need the name from the path
+      List<String> parts = newArrayList(Splitter.on('/').split(request.getEndpoint().getPath()));
+      checkArgument(parts.size() > 0);
+      
+      return CDNContainer.builder().name(parts.get(parts.size() - 1))
+            .enabled(Boolean.parseBoolean(enabled))
+            .logRetention(Boolean.parseBoolean(logRetention))
+            .ttl(Integer.parseInt(ttl))
+            .uri(URI.create(uri))
+            .sslUri(URI.create(sslUri))
+            .streamingUri(URI.create(streamingUri))
+            .iosUri(URI.create(iosUri))
+            .build();
+   }
+
+   @Override
+   public ParseCDNContainerFromHeaders setContext(HttpRequest request) {
+      this.request = request;
+      return this;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/ParseCDNContainerURIFromHeaders.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/ParseCDNContainerURIFromHeaders.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/ParseCDNContainerURIFromHeaders.java
new file mode 100644
index 0000000..4a29f60
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/ParseCDNContainerURIFromHeaders.java
@@ -0,0 +1,45 @@
+/*
+ * 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.rackspace.cloudfiles.v1.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+
+import org.jclouds.http.HttpResponse;
+import org.jclouds.rackspace.cloudfiles.v1.domain.CDNContainer;
+import org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders;
+
+import com.google.common.base.Function;
+
+/**
+ * Parses the {@link CDNContainer} from the response headers.
+ * 
+ * @author Jeremy Daggett
+ *
+ */
+public class ParseCDNContainerURIFromHeaders implements Function<HttpResponse, URI> {
+
+   /**
+    * parses the http response headers to provide the CDN URI string.
+    */
+   public URI apply(final HttpResponse from) {
+      String cdnUri = checkNotNull(from.getFirstHeaderOrNull(CloudFilesHeaders.CDN_URI),
+               CloudFilesHeaders.CDN_URI);
+      return URI.create(cdnUri);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/RegionToCDNEndpoint.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/RegionToCDNEndpoint.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/RegionToCDNEndpoint.java
new file mode 100644
index 0000000..3b5361a
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/functions/RegionToCDNEndpoint.java
@@ -0,0 +1,77 @@
+/*
+ * 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.rackspace.cloudfiles.v1.functions;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.net.URI;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.functions.RegionToEndpoint;
+import org.jclouds.location.suppliers.RegionIdToURISupplier;
+import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApi;
+import org.jclouds.rackspace.cloudfiles.v1.features.CDNApi;
+import org.jclouds.rackspace.cloudidentity.v2_0.ServiceType;
+import org.jclouds.rest.annotations.ApiVersion;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+
+/**
+ * This class ensures that the correct Cloud Files CDN endpoint is retrieved from the endpoint 
+ * supplier. The CDN API should never be instantiated directly, but rather accessed through the 
+ * {@link CloudFilesApi#cdnApiInRegion(String)} API.
+ * <p/>
+ * <h3>NOTE</h3>
+ * The Cloud Files Service Type will always default to OpenStack Object Storage ("object-storage").
+ * <p/>
+ * 
+ * @author Jeremy Daggett
+ * 
+ * @see CloudFilesApi#cdnApiInRegion(String)
+ * @see CDNApi
+ * @see RegionToEndpoint
+ * @see org.jclouds.openstack.v2_0.ServiceType#OBJECT_STORE
+ * @see org.jclouds.rackspace.cloudidentity.v2_0.ServiceType#OBJECT_CDN
+ * @see <a
+ *      href="http://docs.rackspace.com/files/api/v1/cf-devguide/content/Service-Access-Endpoints-d1e003.html">
+ *      Service Access Endpoints</a>
+ */
+@Singleton
+public class RegionToCDNEndpoint implements Function<Object, URI> { 
+
+   private final Supplier<Map<String, Supplier<URI>>> endpointsSupplier;
+
+   @Inject
+   public RegionToCDNEndpoint(@ApiVersion final String apiVersion, final RegionIdToURISupplier.Factory factory) {
+      this.endpointsSupplier = factory.createForApiTypeAndVersion(ServiceType.OBJECT_CDN, apiVersion);
+   }
+
+   public URI apply(@Nullable Object from) {
+      checkArgument(from != null && from instanceof String, "you must specify a region, as a String argument");
+      Map<String, Supplier<URI>> regionToEndpoint = endpointsSupplier.get();
+      checkState(regionToEndpoint.size() > 0, "no region name to endpoint mappings configured!");
+      checkArgument(regionToEndpoint.containsKey(from),
+            "requested location %s, which is not in the configured locations: %s", from, regionToEndpoint);
+      return regionToEndpoint.get(from).get();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/handlers/CloudFilesErrorHandler.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/handlers/CloudFilesErrorHandler.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/handlers/CloudFilesErrorHandler.java
new file mode 100644
index 0000000..1e69b23
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/handlers/CloudFilesErrorHandler.java
@@ -0,0 +1,91 @@
+/*
+ * 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.rackspace.cloudfiles.v1.handlers;
+
+import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.jclouds.blobstore.ContainerNotFoundException;
+import org.jclouds.blobstore.KeyNotFoundException;
+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;
+import org.jclouds.rest.InsufficientResourcesException;
+
+// TODO: is there error spec someplace? let's type errors, etc.
+public class CloudFilesErrorHandler implements HttpErrorHandler {
+   public static final String PREFIX = "^/v[0-9][^/]*/[a-zA-Z]+_[^/]+/";
+   public static final Pattern CONTAINER_PATH = Pattern.compile(PREFIX + "([^/]+)$");
+   public static final Pattern CONTAINER_KEY_PATH = Pattern.compile(PREFIX + "([^/]+)/(.*)");
+
+   public void handleError(HttpCommand command, HttpResponse response) {
+      // it is important to always read fully and close streams
+      byte[] data = closeClientButKeepContentStream(response);
+      String message = data != null ? new String(data) : null;
+
+      Exception exception = message != null ? new HttpResponseException(command, response, message)
+               : new HttpResponseException(command, response);
+      message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(),
+               response.getStatusLine());
+      switch (response.getStatusCode()) {
+         case 401:
+            exception = new AuthorizationException(exception.getMessage(), exception);
+            break;
+         case 404:
+            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);
+               
+               if (matcher.find()) {
+                  exception = new ContainerNotFoundException(matcher.group(1), message);
+                  exception.initCause(oldException);
+               } else {
+                  matcher = CONTAINER_KEY_PATH.matcher(path);
+                  if (matcher.find()) {
+                     exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), message);
+                     exception.initCause(oldException);
+                  }
+               }
+            }
+            break;
+         case 409:
+            exception = new IllegalStateException(exception.getMessage(), exception);
+            break;
+         case 413:
+            exception = new InsufficientResourcesException(exception.getMessage(), exception);
+            break;
+      }
+      command.setException(exception);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/options/UpdateCDNContainerOptions.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/options/UpdateCDNContainerOptions.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/options/UpdateCDNContainerOptions.java
new file mode 100644
index 0000000..d044657
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/options/UpdateCDNContainerOptions.java
@@ -0,0 +1,163 @@
+/*
+
+ * 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.rackspace.cloudfiles.v1.options;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_ENABLED;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_LOG_RETENTION;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_TTL;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_TTL_MAX;
+import static org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders.CDN_TTL_MIN;
+
+import org.jclouds.http.options.BaseHttpRequestOptions;
+
+/**
+ * Contains options supported in the REST API for updating CDN containers.
+ * 
+ * <a href=
+ *    "http://docs.rackspace.com/files/api/v1/cf-devguide/content/Update_CDN-Enabled_Container_Metadata-d1e2787.html">
+ *    Update CDN container</a>.
+ *
+ * @author Jeremy Daggett
+ */
+public class UpdateCDNContainerOptions extends BaseHttpRequestOptions {
+   public static final UpdateCDNContainerOptions NONE = new UpdateCDNContainerOptions();
+
+   /** 
+    * Updates TTL
+    */
+   public UpdateCDNContainerOptions ttl(int ttl) {
+      checkState(ttl >= Integer.valueOf(CDN_TTL_MIN), "ttl must be >= " + CDN_TTL_MIN);
+      checkState(ttl <= Integer.valueOf(CDN_TTL_MAX), "ttl must be <= " + CDN_TTL_MAX);
+      headers.put(CDN_TTL, Integer.toString(ttl));
+      return this;
+   }
+
+   /** 
+    * Enables or disables log retention
+    */
+   public UpdateCDNContainerOptions logRetention(boolean logRetention) {
+      headers.put(CDN_LOG_RETENTION, Boolean.toString(logRetention));
+      return this;
+   }
+
+   /** 
+    * Enables or disables the CDN Container
+    * API to enable disable - is this necessary?
+    */
+   public UpdateCDNContainerOptions enabled(boolean enabled) {
+      headers.put(CDN_ENABLED, Boolean.toString(enabled));
+      return this;
+   }
+   
+   /**
+    * Sets the index page for the Static Website.
+    */
+   public UpdateCDNContainerOptions staticWebsiteIndexPage(String indexPage) {
+      checkNotNull(indexPage, "index page cannot be null");
+      headers.put("indexPage", indexPage);
+      return this;
+   }
+
+   /**
+    * Sets the error page for the Static Website.
+    */
+   public UpdateCDNContainerOptions staticWebsiteErrorPage(String errorPage) {
+      checkNotNull(errorPage, "error page cannot be null");
+      headers.put("errorPage", errorPage);
+      return this;
+   }
+
+   /**
+    * Enables or disables listings for the Static Website.
+    */
+   public UpdateCDNContainerOptions staticWebsiteListings(boolean listings) {
+      headers.put("enableListings", Boolean.toString(listings));
+      return this;
+   }
+   
+   /**
+    * Sets the CSS pages for the Static Website.
+    */
+   public UpdateCDNContainerOptions staticWebsiteListingsCSS(String listingsCSS) {
+      checkNotNull(listingsCSS, "listingsCSS page cannot be null");
+      headers.put("limit", listingsCSS);
+      return this;
+   }
+
+   public static class Builder {
+      /** @see UpdateCDNContainerOptions#ttl */
+      public static UpdateCDNContainerOptions ttl(int ttl) {
+         UpdateCDNContainerOptions options = new UpdateCDNContainerOptions();
+         return options.ttl(ttl);
+      }
+
+      /** 
+       * @see UpdateCDNContainerOptions#logRetention 
+       */
+      public static UpdateCDNContainerOptions logRetention(boolean logRetention) {
+         UpdateCDNContainerOptions options = new UpdateCDNContainerOptions();
+         return options.logRetention(logRetention);
+      }
+
+      /** 
+       * @see UpdateCDNContainerOptions#enabled
+       */
+      public static UpdateCDNContainerOptions enabled(boolean enabled) {
+         UpdateCDNContainerOptions options = new UpdateCDNContainerOptions();
+         return options.enabled(enabled);
+      }
+
+      /** 
+       * @see UpdateCDNContainerOptions#staticWebsiteIndexPage 
+       */
+      public static UpdateCDNContainerOptions staticWebsiteIndexPage(String indexPage) {
+         UpdateCDNContainerOptions options = new UpdateCDNContainerOptions();
+         return options.staticWebsiteIndexPage(indexPage);
+      }
+
+      /** 
+       * @see UpdateCDNContainerOptions#staticWebsiteErrorPage 
+       */
+      public static UpdateCDNContainerOptions staticWebsiteErrorPage(String errorPage) {
+         UpdateCDNContainerOptions options = new UpdateCDNContainerOptions();
+         return options.staticWebsiteErrorPage(errorPage);
+      }
+
+      /** 
+       * @see UpdateCDNContainerOptions#staticWebsiteListings 
+       */
+      public static UpdateCDNContainerOptions staticWebsiteListings(boolean enabled) {
+         UpdateCDNContainerOptions options = new UpdateCDNContainerOptions();
+         return options.staticWebsiteListings(enabled);
+      }
+
+      /** 
+       * @see UpdateCDNContainerOptions#staticWebsiteListingsCSS 
+       */
+      public static UpdateCDNContainerOptions staticWebsiteListingsCSS(String cssPage) {
+         UpdateCDNContainerOptions options = new UpdateCDNContainerOptions();
+         return options.staticWebsiteListingsCSS(cssPage);
+      }
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/reference/CloudFilesHeaders.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/reference/CloudFilesHeaders.java b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/reference/CloudFilesHeaders.java
new file mode 100644
index 0000000..7247700
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/reference/CloudFilesHeaders.java
@@ -0,0 +1,58 @@
+/*
+ * 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.rackspace.cloudfiles.v1.reference;
+
+import org.jclouds.openstack.swift.v1.reference.SwiftHeaders;
+
+/**
+ * Additional headers specified by Rackspace Cloud Files CDN.
+ * 
+ * @see <a
+ *      href="http://docs.rackspace.com/files/api/v1/cf-devguide/content/index.html">
+ *      Cloud Files API</a>
+ *      
+ * @author Jeremy Daggett
+ */
+public interface CloudFilesHeaders extends SwiftHeaders {
+   // Access logs
+   String CONTAINER_ACCESS_LOG_DELIVERY = CONTAINER_METADATA_PREFIX + "Access-Log-Delivery";
+
+   // Common CDN Headers
+   String CDN_ENABLED = "X-Cdn-Enabled";
+   String CDN_LOG_RETENTION = "X-Log-Retention";
+   String CDN_TTL = "X-Ttl";
+   String CDN_URI = "X-Cdn-Uri";
+   String CDN_SSL_URI = "X-Cdn-Ssl-Uri";
+   String CDN_STREAMING_URI = "X-Cdn-Streaming-Uri";
+   String CDN_IOS_URI = "X-Cdn-Ios-Uri";
+   
+   // CDN TTL Limits
+   int CDN_TTL_MIN = 900;
+   int CDN_TTL_MAX = 31536000;
+   int CDN_TTL_DEFAULT = 259200;
+
+   // CDN Purge
+   String CDN_PURGE_OBJECT_EMAIL = "X-Purge-Email";
+   String CDN_PURGE_OBJECT_FAILED = "X-Purge-Failed-Reason";
+   
+   // CDN Static Web
+   String STATIC_WEB_INDEX = CONTAINER_METADATA_PREFIX + "Web-Index";
+   String STATIC_WEB_DIRECTORY_TYPE = CONTAINER_METADATA_PREFIX + "Web-Directory-Type";
+   String STATIC_WEB_ERROR = CONTAINER_METADATA_PREFIX + "Web-Error";
+   String STATIC_WEB_LISTINGS = CONTAINER_METADATA_PREFIX + "Web-Listings";
+   String STATIC_WEB_LISTINGS_CSS = CONTAINER_METADATA_PREFIX + "Web-Listings-CSS";
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata b/rackspace-cloudfiles/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata
new file mode 100644
index 0000000..9be2b32
--- /dev/null
+++ b/rackspace-cloudfiles/src/main/resources/META-INF/services/org.jclouds.apis.ApiMetadata
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.jclouds.rackspace.cloudfiles.v1.CloudFilesApiMetadata

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiLiveTest.java
new file mode 100644
index 0000000..666059f
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiLiveTest.java
@@ -0,0 +1,30 @@
+/*
+ * 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.rackspace.cloudfiles.v1;
+
+import org.jclouds.rackspace.cloudfiles.v1.internal.BaseCloudFilesApiLiveTest;
+import org.testng.annotations.Test;
+
+/**
+ * Tests behavior of {@code CloudFilesApi}
+ * 
+ * @author Jeremy Daggett
+ */
+@Test(groups = "live", testName = "CloudFilesApiLiveTest")
+public class CloudFilesApiLiveTest extends BaseCloudFilesApiLiveTest {
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadataTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadataTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadataTest.java
new file mode 100644
index 0000000..5c32f1c
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadataTest.java
@@ -0,0 +1,35 @@
+package org.jclouds.rackspace.cloudfiles.v1;
+/*
+ * 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.
+ */
+
+import org.jclouds.View;
+import org.jclouds.apis.internal.BaseApiMetadataTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * 
+ * @author Jeremy Daggett
+ */
+@Test(groups = "unit", testName = "CloudFilesApiMetadataTest")
+public class CloudFilesApiMetadataTest extends BaseApiMetadataTest {
+   public CloudFilesApiMetadataTest() {
+      super(new CloudFilesApiMetadata(), ImmutableSet.<TypeToken<? extends View>> of());
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/binders/BindCDNPurgeEmailAddressesToHeadersMockTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/binders/BindCDNPurgeEmailAddressesToHeadersMockTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/binders/BindCDNPurgeEmailAddressesToHeadersMockTest.java
new file mode 100644
index 0000000..5c7e2b0
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/binders/BindCDNPurgeEmailAddressesToHeadersMockTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.rackspace.cloudfiles.v1.binders;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.List;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
+import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApi;
+import org.jclouds.rackspace.cloudfiles.v1.reference.CloudFilesHeaders;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Tests behavior of {@code BindCDNPurgeEmailAddressesToHeaders}
+ * 
+ * @author Jeremy Daggett
+ */
+@Test(groups = "unit", testName = "BindCDNPurgeEmailAddressesToHeadersMockTest")
+public class BindCDNPurgeEmailAddressesToHeadersMockTest extends BaseOpenStackMockTest<CloudFilesApi> {
+
+   BindCDNPurgeEmailAddressesToHeaders binder = new BindCDNPurgeEmailAddressesToHeaders();
+
+   public void testEmailBind() throws Exception {
+      List<String> emails = ImmutableList.of("foo@bar.com", "bar@foo.com");
+
+      HttpRequest request = purgeRequest();
+      
+      HttpRequest actualRequest = binder.bindToRequest(request, emails);
+      
+      HttpRequest expectedRequest = HttpRequest.builder()
+            .method("DELETE")
+            .endpoint("https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_XXXXXX/")
+            .addHeader(CloudFilesHeaders.CDN_PURGE_OBJECT_EMAIL, "foo@bar.com, bar@foo.com")
+            .build(); 
+      
+      assertEquals(actualRequest, expectedRequest);
+      
+   }
+
+   @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "input")
+   public void testNullList() {
+      HttpRequest request = purgeRequest();
+      binder.bindToRequest(request, null);
+   }
+
+   @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "request")
+   public void testNullRequest() {
+      List<String> emails = ImmutableList.of("foo@bar.com", "bar@foo.com");
+      binder.bindToRequest(null, emails);
+   }
+   
+   private static final HttpRequest purgeRequest() {
+      return HttpRequest.builder()
+                .method("DELETE")
+                .endpoint("https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_XXXXXX/")
+                .build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/CloudFilesRegionScopedBlobStoreContextLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/CloudFilesRegionScopedBlobStoreContextLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/CloudFilesRegionScopedBlobStoreContextLiveTest.java
new file mode 100644
index 0000000..bc35b3a
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/CloudFilesRegionScopedBlobStoreContextLiveTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.rackspace.cloudfiles.v1.blobstore;
+
+import static org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes.API_KEY_CREDENTIALS;
+
+import java.util.Properties;
+
+import org.jclouds.openstack.swift.v1.blobstore.RegionScopedBlobStoreContextLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live")
+public class CloudFilesRegionScopedBlobStoreContextLiveTest extends RegionScopedBlobStoreContextLiveTest {
+
+   public CloudFilesRegionScopedBlobStoreContextLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+
+   @Override
+   protected Properties setupProperties() {
+      Properties props = super.setupProperties();
+      setIfTestSystemPropertyPresent(props, API_KEY_CREDENTIALS);
+      return props;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobIntegrationLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobIntegrationLiveTest.java
new file mode 100644
index 0000000..58ed73b
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobIntegrationLiveTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.rackspace.cloudfiles.v1.blobstore.integration;
+
+import static org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes.API_KEY_CREDENTIALS;
+
+import java.util.Properties;
+
+import org.jclouds.openstack.swift.v1.blobstore.integration.SwiftBlobIntegrationLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesBlobIntegrationLiveTest")
+public class CloudFilesBlobIntegrationLiveTest extends SwiftBlobIntegrationLiveTest {
+
+   public CloudFilesBlobIntegrationLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+   
+   @Override
+   protected Properties setupProperties() {
+      Properties props = super.setupProperties();
+      setIfTestSystemPropertyPresent(props, API_KEY_CREDENTIALS);
+      return props;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobLiveTest.java
new file mode 100644
index 0000000..87519d5
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobLiveTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.rackspace.cloudfiles.v1.blobstore.integration;
+
+import static org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes.API_KEY_CREDENTIALS;
+
+import java.util.Properties;
+
+import org.jclouds.openstack.swift.v1.blobstore.integration.SwiftBlobLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesBlobLiveTest")
+public class CloudFilesBlobLiveTest extends SwiftBlobLiveTest {
+
+   public CloudFilesBlobLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+
+   @Override
+   protected Properties setupProperties() {
+      Properties props = super.setupProperties();
+      setIfTestSystemPropertyPresent(props, API_KEY_CREDENTIALS);
+      return props;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobSignerLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobSignerLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobSignerLiveTest.java
new file mode 100644
index 0000000..dea68f2
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesBlobSignerLiveTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.rackspace.cloudfiles.v1.blobstore.integration;
+
+import static org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes.API_KEY_CREDENTIALS;
+
+import java.util.Properties;
+
+import org.jclouds.openstack.swift.v1.blobstore.integration.SwiftBlobSignerLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesBlobSignerLiveTest")
+public class CloudFilesBlobSignerLiveTest extends SwiftBlobSignerLiveTest {
+
+   public CloudFilesBlobSignerLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+
+   @Override
+   protected Properties setupProperties() {
+      Properties props = super.setupProperties();
+      setIfTestSystemPropertyPresent(props, API_KEY_CREDENTIALS);
+      return props;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesContainerIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesContainerIntegrationLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesContainerIntegrationLiveTest.java
new file mode 100644
index 0000000..ba99a75
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesContainerIntegrationLiveTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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.rackspace.cloudfiles.v1.blobstore.integration;
+
+import static org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes.API_KEY_CREDENTIALS;
+
+import java.util.Properties;
+
+import org.jclouds.openstack.swift.v1.blobstore.integration.SwiftContainerIntegrationLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesContainerIntegrationLiveTest")
+public class CloudFilesContainerIntegrationLiveTest extends SwiftContainerIntegrationLiveTest {
+
+   public CloudFilesContainerIntegrationLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+
+   @Override
+   protected Properties setupProperties() {
+      Properties props = super.setupProperties();
+      setIfTestSystemPropertyPresent(props, API_KEY_CREDENTIALS);
+      return props;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesContainerLiveTest.java
----------------------------------------------------------------------
diff --git a/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesContainerLiveTest.java b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesContainerLiveTest.java
new file mode 100644
index 0000000..98ab003
--- /dev/null
+++ b/rackspace-cloudfiles/src/test/java/org/jclouds/rackspace/cloudfiles/v1/blobstore/integration/CloudFilesContainerLiveTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.rackspace.cloudfiles.v1.blobstore.integration;
+
+import static org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes.API_KEY_CREDENTIALS;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Properties;
+
+import org.jclouds.openstack.swift.v1.blobstore.integration.SwiftContainerLiveTest;
+import org.testng.SkipException;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "CloudFilesContainerLiveTest")
+public class CloudFilesContainerLiveTest extends SwiftContainerLiveTest {
+
+   public CloudFilesContainerLiveTest() {
+      provider = "rackspace-cloudfiles";
+   }
+
+   @Override
+   public void testPublicAccess() throws InterruptedException, MalformedURLException, IOException {
+      throw new SkipException("public access only supported through CDN");
+   }
+   
+   @Override
+   public void testPublicAccessInNonDefaultLocationWithBigBlob() throws InterruptedException, MalformedURLException, IOException {
+      throw new SkipException("public access only supported through CDN");
+   }
+   
+   public void testPublicAccessInNonDefaultLocation() throws InterruptedException, MalformedURLException, IOException {
+      throw new SkipException("public access only supported through CDN");
+   }
+   
+   @Override
+   protected Properties setupProperties() {
+      Properties props = super.setupProperties();
+      setIfTestSystemPropertyPresent(props, API_KEY_CREDENTIALS);
+      return props;
+   }
+}


[4/5] JCLOUDS-423 - Adds support for Rackspace Cloud Files API - Added support for CloudFilesApi/CDNApi - Added mock/live tests - Refactored listFirstPage() and listAt() API methods to list() and listWithOptions(…) - General Swift API cleanup: docs and t

Posted by za...@apache.org.
http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
index 8b6637f..b884f30 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
@@ -32,6 +32,7 @@ import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindObjectMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.domain.Segment;
+import org.jclouds.openstack.swift.v1.domain.SwiftObject;
 import org.jclouds.openstack.swift.v1.functions.ETagHeader;
 import org.jclouds.rest.annotations.BinderParam;
 import org.jclouds.rest.annotations.Fallback;
@@ -41,9 +42,10 @@ import org.jclouds.rest.annotations.ResponseParser;
 import org.jclouds.rest.binders.BindToJsonPayload;
 
 /**
- * @see <a
- *      href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/static-large-objects.html">
- *      Static Large Objects API</a>
+ * Provides access to the Swift Static Large Object API features.
+ * 
+ * @author Adrian Cole
+ * @author Jeremy Daggett
  */
 @RequestFilters(AuthenticateRequest.class)
 @Consumes(APPLICATION_JSON)
@@ -53,16 +55,16 @@ public interface StaticLargeObjectApi {
     * Creates or updates a static large object's manifest.
     * 
     * @param objectName
-    *           corresponds to {@link SwiftObject#name()}.
+    *           corresponds to {@link SwiftObject#getName()}.
     * @param segments
     *           ordered parts which will be concatenated upon download.
     * @param metadata
-    *           corresponds to {@link SwiftObject#metadata()}.
+    *           corresponds to {@link SwiftObject#getMetadata()}.
     * 
-    * @return {@link SwiftObject#etag()} of the object, which is the MD5
+    * @return {@link SwiftObject#getEtag()} of the object, which is the MD5
     *         checksum of the concatenated ETag values of the {@code segments}.
     */
-   @Named("CreateOrUpdateStaticLargeObjectManifest")
+   @Named("staticLargeObject:replaceManifest")
    @PUT
    @ResponseParser(ETagHeader.class)
    @Path("/{objectName}")
@@ -75,9 +77,9 @@ public interface StaticLargeObjectApi {
     * Deletes a static large object, if present, including all of its segments.
     * 
     * @param objectName
-    *           corresponds to {@link SwiftObject#name()}.
+    *           corresponds to {@link SwiftObject#getName()}.
     */
-   @Named("DeleteStaticLargeObject")
+   @Named("staticLargeObject:delete")
    @DELETE
    @Fallback(VoidOnNotFoundOr404.class)
    @Path("/{objectName}")

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java
index 06f0eaf..27e3741 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/EntriesWithoutMetaPrefix.java
@@ -29,9 +29,7 @@ import com.google.common.collect.Multimap;
  * @param from
  *           a {@link Multimap} containing the prefixed headers.
  * 
- * @return the extracted {@code Metadata} without the prefixed keys.
- * 
- * @see {@link SwiftResource#metadata()}
+ * @return the extracted metadata without the prefixed keys. 
  */
 enum EntriesWithoutMetaPrefix implements Function<Multimap<String, String>, Map<String, String>> {
    INSTANCE;

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountFromHeaders.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountFromHeaders.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountFromHeaders.java
index f31cbac..9debe67 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountFromHeaders.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseAccountFromHeaders.java
@@ -16,6 +16,10 @@
  */
 package org.jclouds.openstack.swift.v1.functions;
 
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_BYTES_USED;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_CONTAINER_COUNT;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_OBJECT_COUNT;
+
 import org.jclouds.http.HttpResponse;
 import org.jclouds.openstack.swift.v1.domain.Account;
 
@@ -25,10 +29,10 @@ public class ParseAccountFromHeaders implements Function<HttpResponse, Account>
 
    @Override
    public Account apply(HttpResponse from) {
-      return Account.builder() //
-            .bytesUsed(Long.parseLong(from.getFirstHeaderOrNull("X-Account-Bytes-Used"))) //
-            .containerCount(Long.parseLong(from.getFirstHeaderOrNull("X-Account-Container-Count"))) //
-            .objectCount(Long.parseLong(from.getFirstHeaderOrNull("X-Account-Object-Count"))) //
+      return Account.builder()
+            .bytesUsed(Long.parseLong(from.getFirstHeaderOrNull(ACCOUNT_BYTES_USED)))
+            .containerCount(Long.parseLong(from.getFirstHeaderOrNull(ACCOUNT_CONTAINER_COUNT)))
+            .objectCount(Long.parseLong(from.getFirstHeaderOrNull(ACCOUNT_OBJECT_COUNT)))
             .metadata(EntriesWithoutMetaPrefix.INSTANCE.apply(from.getHeaders())).build();
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
index 5fb3c9f..d616351 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
@@ -16,6 +16,11 @@
  */
 package org.jclouds.openstack.swift.v1.functions;
 
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_ACL_ANYBODY_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_BYTES_USED;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_OBJECT_COUNT;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_READ;
+
 import org.jclouds.http.HttpRequest;
 import org.jclouds.http.HttpResponse;
 import org.jclouds.openstack.swift.v1.domain.Container;
@@ -31,12 +36,14 @@ public class ParseContainerFromHeaders implements Function<HttpResponse, Contain
 
    @Override
    public Container apply(HttpResponse from) {
-      return Container.builder() //
-            .name(name) //
-            .bytesUsed(Long.parseLong(from.getFirstHeaderOrNull("X-Container-Bytes-Used"))) //
-            .objectCount(Long.parseLong(from.getFirstHeaderOrNull("X-Container-Object-Count"))) //
-            .anybodyRead(".r:*,.rlistings".equals(from.getFirstHeaderOrNull("X-Container-Read"))) //
+      Container c = 
+      Container.builder()
+            .name(name)
+            .bytesUsed(Long.parseLong(from.getFirstHeaderOrNull(CONTAINER_BYTES_USED)))
+            .objectCount(Long.parseLong(from.getFirstHeaderOrNull(CONTAINER_OBJECT_COUNT)))
+            .anybodyRead(CONTAINER_ACL_ANYBODY_READ.equals(from.getFirstHeaderOrNull(CONTAINER_READ)))
             .metadata(EntriesWithoutMetaPrefix.INSTANCE.apply(from.getHeaders())).build();
+      return c;
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java
index 158aa6d..6c1ac9e 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectFromResponse.java
@@ -46,12 +46,12 @@ public class ParseObjectFromResponse implements Function<HttpResponse, SwiftObje
 
    @Override
    public SwiftObject apply(HttpResponse from) {
-      return SwiftObject.builder() //
-            .uri(URI.create(uri)) //
-            .name(name) //
-            .etag(from.getFirstHeaderOrNull(ETAG)) //
-            .payload(from.getPayload()) //
-            .lastModified(dates.rfc822DateParse(from.getFirstHeaderOrNull(LAST_MODIFIED))) //
+      return SwiftObject.builder()
+            .uri(URI.create(uri))
+            .name(name)
+            .etag(from.getFirstHeaderOrNull(ETAG))
+            .payload(from.getPayload())
+            .lastModified(dates.rfc822DateParse(from.getFirstHeaderOrNull(LAST_MODIFIED)))
             .headers(from.getHeaders())
             .metadata(EntriesWithoutMetaPrefix.INSTANCE.apply(from.getHeaders())).build();
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
index 5cfa562..0b58e8b 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
@@ -74,11 +74,11 @@ public class ParseObjectListFromResponse implements Function<HttpResponse, Objec
 
       @Override
       public SwiftObject apply(InternalObject input) {
-         return SwiftObject.builder() //
-               .uri(URI.create(String.format("%s%s", containerUri, input.name))) //
-               .name(input.name) //
-               .etag(input.hash) //
-               .payload(payload(input.bytes, input.content_type)) //
+         return SwiftObject.builder()
+               .uri(URI.create(String.format("%s%s", containerUri, input.name)))
+               .name(input.name)
+               .etag(input.hash)
+               .payload(payload(input.bytes, input.content_type))
                .lastModified(input.last_modified).build();
       }
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 2fe469e..2bde41c 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
@@ -30,6 +30,7 @@ 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;
+import org.jclouds.rest.InsufficientResourcesException;
 
 // TODO: is there error spec someplace? let's type errors, etc.
 public class SwiftErrorHandler implements HttpErrorHandler {
@@ -81,6 +82,9 @@ public class SwiftErrorHandler implements HttpErrorHandler {
          case 409:
             exception = new IllegalStateException(exception.getMessage(), exception);
             break;
+         case 413:
+            exception = new InsufficientResourcesException(exception.getMessage(), exception);
+            break;
       }
       command.setException(exception);
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 fc8f9c8..cef386a 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
@@ -16,22 +16,29 @@
  */
 package org.jclouds.openstack.swift.v1.options;
 
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_ACL_ANYBODY_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_VERSIONS_LOCATION;
+
 import java.util.Map;
 
 import org.jclouds.http.options.BaseHttpRequestOptions;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders;
+import org.jclouds.openstack.swift.v1.domain.Container;
+import org.jclouds.openstack.swift.v1.features.ContainerApi;
 
 /**
- * Options available to <a href=
- * "http://docs.openstack.org/api/openstack-object-storage/1.0/content/create-container.html"
- * >create a container</a>.
+ * Options for creating a {@link Container}. 
  * 
- * @see ContainerApi#createIfAbsent
+ * @see ContainerApi#createIfAbsent(String, CreateContainerOptions)
  */
 public class CreateContainerOptions extends BaseHttpRequestOptions {
    public static final CreateContainerOptions NONE = new CreateContainerOptions();
 
-   /** corresponds to {@link Container#metadata()} */
+   /** 
+    * Sets the metadata on a container at creation. 
+    */
    public CreateContainerOptions metadata(Map<String, String> metadata) {
       if (!metadata.isEmpty()) {
          this.headers.putAll(bindMetadataToHeaders.toHeaders(metadata));
@@ -39,26 +46,48 @@ public class CreateContainerOptions extends BaseHttpRequestOptions {
       return this;
    }
 
-   /** Sets the ACL the container so that anybody can read it. */
+   /** 
+    * Sets the public ACL on the container so that anybody can read it. 
+    */
    public CreateContainerOptions anybodyRead() {
-      this.headers.put("x-container-read", ".r:*,.rlistings");
+      this.headers.put(CONTAINER_READ, CONTAINER_ACL_ANYBODY_READ);
+      return this;
+   }
+
+   /** 
+    * Sets the container that will contain object versions.
+    */
+   public CreateContainerOptions versionsLocation(String containerName) {
+      this.headers.put(CONTAINER_VERSIONS_LOCATION, containerName);
       return this;
    }
 
    public static class Builder {
 
-      /** @see CreateContainerOptions#anybodyRead */
+      /** 
+       * @see CreateContainerOptions#anybodyRead 
+       */
       public static CreateContainerOptions anybodyRead() {
          CreateContainerOptions options = new CreateContainerOptions();
          return options.anybodyRead();
       }
 
-      /** @see CreateContainerOptions#metadata */
+      /** 
+       * @see CreateContainerOptions#metadata 
+       */
       public static CreateContainerOptions metadata(Map<String, String> metadata) {
          CreateContainerOptions options = new CreateContainerOptions();
          return options.metadata(metadata);
       }
+
+      /** 
+       * @see CreateContainerOptions#versionsLocation 
+       */
+      public static CreateContainerOptions versionsLocation(String containerName) {
+         CreateContainerOptions options = new CreateContainerOptions();
+         return options.versionsLocation(containerName);
+      }
    }
 
-   private static final BindMetadataToHeaders bindMetadataToHeaders = new BindMetadataToHeaders("x-container-meta-");
+   private static final BindMetadataToHeaders bindMetadataToHeaders = new BindMetadataToHeaders(CONTAINER_METADATA_PREFIX);
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainerOptions.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainerOptions.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainerOptions.java
index 3373455..e1003e4 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainerOptions.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainerOptions.java
@@ -20,18 +20,19 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 
 import org.jclouds.http.options.BaseHttpRequestOptions;
+import org.jclouds.openstack.swift.v1.features.ContainerApi;
 
 /**
- * Options available for <a href=
- * "http://docs.openstack.org/api/openstack-object-storage/1.0/content/list-objects.html"
- * >listing objects</a>.
+ * Options for listing containers. 
  * 
- * @see ObjectApi#list
+ * @see ContainerApi#list(ListContainerOptions)
  */
 public class ListContainerOptions extends BaseHttpRequestOptions {
    public static final ListContainerOptions NONE = new ListContainerOptions();
 
-   /** list operation returns no more than this amount. */
+   /** 
+    * list operation returns no more than this amount. 
+    */
    public ListContainerOptions limit(int limit) {
       checkState(limit >= 0, "limit must be >= 0");
       checkState(limit <= 10000, "limit must be <= 10000");
@@ -39,31 +40,41 @@ public class ListContainerOptions extends BaseHttpRequestOptions {
       return this;
    }
 
-   /** object names greater in value than the specified marker are returned. */
+   /** 
+    * object names greater in value than the specified marker are returned.
+    */
    public ListContainerOptions marker(String marker) {
       queryParameters.put("marker", checkNotNull(marker, "marker"));
       return this;
    }
 
-   /** object names less in value than the specified marker are returned. */
+   /** 
+    * object names less in value than the specified marker are returned.
+    */
    public ListContainerOptions endMarker(String endMarker) {
       queryParameters.put("end_marker", checkNotNull(endMarker, "endMarker"));
       return this;
    }
 
-   /** object names beginning with this substring are returned. */
+   /** 
+    * object names beginning with this substring are returned.
+    */
    public ListContainerOptions prefix(String prefix) {
       queryParameters.put("prefix", checkNotNull(prefix, "prefix"));
       return this;
    }
 
-   /** object names nested in the container are returned. */
+   /** 
+    * object names nested in the container are returned.
+    */
    public ListContainerOptions delimiter(char delimiter) {
       queryParameters.put("delimiter", Character.toString(delimiter));
       return this;
    }
 
-   /** object names nested in the pseudo path are returned. */
+   /** 
+    * object names nested in the pseudo path are returned.
+    */
    public ListContainerOptions path(String path) {
       queryParameters.put("path", checkNotNull(path, "path"));
       return this;
@@ -71,37 +82,49 @@ public class ListContainerOptions extends BaseHttpRequestOptions {
 
    public static class Builder {
 
-      /** @see ListContainerOptions#limit */
+      /** 
+       * @see ListContainerOptions#limit
+       */
       public static ListContainerOptions limit(int limit) {
          ListContainerOptions options = new ListContainerOptions();
          return options.limit(limit);
       }
 
-      /** @see ListContainerOptions#marker */
+      /** 
+       * @see ListContainerOptions#marker
+       */
       public static ListContainerOptions marker(String marker) {
          ListContainerOptions options = new ListContainerOptions();
          return options.marker(marker);
       }
 
-      /** @see ListContainerOptions#endMarker */
+      /** 
+       * @see ListContainerOptions#endMarker
+       */
       public static ListContainerOptions endMarker(String endMarker) {
          ListContainerOptions options = new ListContainerOptions();
          return options.endMarker(endMarker);
       }
 
-      /** @see ListContainerOptions#prefix */
+      /** 
+       * @see ListContainerOptions#prefix 
+       */
       public static ListContainerOptions prefix(String prefix) {
          ListContainerOptions options = new ListContainerOptions();
          return options.prefix(prefix);
       }
 
-      /** @see ListContainerOptions#delimiter */
+      /** 
+       * @see ListContainerOptions#delimiter 
+       */
       public static ListContainerOptions delimiter(char delimiter) {
          ListContainerOptions options = new ListContainerOptions();
          return options.delimiter(delimiter);
       }
 
-      /** @see ListContainerOptions#path */
+      /** 
+       * @see ListContainerOptions#path 
+       */
       public static ListContainerOptions path(String path) {
          ListContainerOptions options = new ListContainerOptions();
          return options.path(path);

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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
index e0c9348..d8bcd5c 100644
--- 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
@@ -22,30 +22,62 @@ package org.jclouds.openstack.swift.v1.reference;
  * @author Jeremy Daggett
  */
 public interface SwiftHeaders {
+   
+   // Common Metadata Prefixes
+   String ACCOUNT_METADATA_PREFIX = "X-Account-Meta-";
+   String CONTAINER_METADATA_PREFIX = "X-Container-Meta-";
+   String OBJECT_METADATA_PREFIX = "X-Object-Meta-";
+   String USER_METADATA_PREFIX = OBJECT_METADATA_PREFIX;
+   
+   // Metadata Removal Prefixes
+   String ACCOUNT_REMOVE_METADATA_PREFIX = "X-Remove-Account-Meta-";
+   String CONTAINER_REMOVE_METADATA_PREFIX = "X-Remove-Container-Meta-";
+   String OBJECT_REMOVE_METADATA_PREFIX = "X-Remove-Object-Meta-";
+   
+   // TempURL
+   String ACCOUNT_TEMPORARY_URL_KEY = ACCOUNT_METADATA_PREFIX + "Temp-Url-Key";
+   String ACCOUNT_TEMPORARY_URL_KEY_2 = ACCOUNT_TEMPORARY_URL_KEY + "-2";
 
-   String USER_METADATA_PREFIX = "X-Object-Meta-"; 
-	
-   String ACCOUNT_TEMPORARY_URL_KEY = "X-Account-Meta-Temp-Url-Key";
+   // Account Headers
    String ACCOUNT_BYTES_USED = "X-Account-Bytes-Used";
    String ACCOUNT_CONTAINER_COUNT = "X-Account-Container-Count";
+   String ACCOUNT_OBJECT_COUNT = "X-Account-Object-Count";
 
+   // Container Headers
    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-";
 
+   // Public access - not supported in all Swift Impls
    String CONTAINER_READ = "X-Container-Read";
    String CONTAINER_WRITE = "X-Container-Write";
+   String CONTAINER_ACL_ANYBODY_READ = ".r:*,.rlistings";
    
-   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";    
-   
+   // CORS
+   String CONTAINER_ACCESS_CONTROL_ALLOW_ORIGIN = CONTAINER_METADATA_PREFIX + "Access-Control-Allow-Origin";
+   String CONTAINER_ACCESS_CONTROL_MAX_AGE = CONTAINER_METADATA_PREFIX + "Access-Control-Max-Age";
+   String CONTAINER_ACCESS_CONTROL_EXPOSE_HEADERS = CONTAINER_METADATA_PREFIX + "Access-Control-Expose-Headers";
+
+   // Container Quota
+   String CONTAINER_QUOTA_BYTES = CONTAINER_METADATA_PREFIX + "Quota-Bytes";
+   String CONTAINER_QUOTA_COUNT = CONTAINER_METADATA_PREFIX + "Quota-Count";
+
+   // Container Sync
+   String CONTAINER_SYNC_KEY = "X-Container-Sync-Key";
+   String CONTAINER_SYNC_TO = "X-Container-Sync-To";
+
+   // Versioning
+   String CONTAINER_VERSIONS_LOCATION = "X-Versions-Location";
+
+   // Misc functionality
+   String CONTAINER_WEB_MODE = "X-Web-Mode";
+
    String OBJECT_COPY_FROM = "X-Copy-From";
    String OBJECT_DELETE_AFTER = "X-Delete-After";
    String OBJECT_DELETE_AT = "X-Delete-At";
+   String OBJECT_MANIFEST = "X-Object-Manifest";  
    /** Get the newest version of the object for GET and HEAD requests */
    String OBJECT_NEWEST = "X-Newest";
-   String OBJECT_VERSIONS_LOCATION = "X-Versions-Location";
+
+   // Static Large Object
+   String STATIC_LARGE_OBJECT = "X-Static-Large-Object";
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 733563c..9a00c14 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
@@ -38,7 +38,7 @@ import org.testng.annotations.Test;
 import com.google.common.collect.ImmutableMap;
 
 @Test(groups = "live", testName = "TemporaryUrlSignerLiveTest")
-public class TemporaryUrlSignerLiveTest extends BaseSwiftApiLiveTest {
+public class TemporaryUrlSignerLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
 
    private String name = getClass().getSimpleName();
    private String containerName = getClass().getSimpleName() + "Container";
@@ -48,10 +48,10 @@ public class TemporaryUrlSignerLiveTest extends BaseSwiftApiLiveTest {
          SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).head(name);
 
          long expires = System.currentTimeMillis() / 1000 + 5;
-         String signature = TemporaryUrlSigner.checkApiEvery(api.accountApiInRegion(regionId), 5) //
-               .sign("GET", object.uri().getPath(), expires);
+         String signature = TemporaryUrlSigner.checkApiEvery(api.accountApiInRegion(regionId), 5)
+               .sign("GET", object.getUri().getPath(), expires);
 
-         URI signed = URI.create(format("%s?temp_url_sig=%s&temp_url_expires=%s", object.uri(), signature, expires));
+         URI signed = URI.create(format("%s?temp_url_sig=%s&temp_url_expires=%s", object.getUri(), signature, expires));
 
          InputStream publicStream = signed.toURL().openStream();
          assertEquals(Strings2.toStringAndClose(publicStream), "swifty");
@@ -74,7 +74,7 @@ public class TemporaryUrlSignerLiveTest extends BaseSwiftApiLiveTest {
       for (String regionId : api.configuredRegions()) {
          api.accountApiInRegion(regionId).updateTemporaryUrlKey(key);
          api.containerApiInRegion(regionId).createIfAbsent(containerName, CreateContainerOptions.NONE);
-         api.objectApiInRegionForContainer(regionId, containerName) //
+         api.objectApiInRegionForContainer(regionId, containerName)
                .replace(name, newStringPayload("swifty"), ImmutableMap.<String, String> of());
       }
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 0f856ba..6744fb6 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
@@ -16,6 +16,7 @@
  */
 package org.jclouds.openstack.swift.v1;
 
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_TEMPORARY_URL_KEY;
 import static org.jclouds.openstack.swift.v1.features.AccountApiMockTest.accountResponse;
 import static org.testng.Assert.assertEquals;
 
@@ -25,7 +26,7 @@ import org.testng.annotations.Test;
 import com.squareup.okhttp.mockwebserver.MockResponse;
 import com.squareup.okhttp.mockwebserver.MockWebServer;
 
-@Test
+@Test(groups = "unit", testName = "TemporaryUrlSignerMockTest")
 public class TemporaryUrlSignerMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    @Test(expectedExceptions = NullPointerException.class, expectedExceptionsMessageRegExp = "accountApi")
@@ -36,7 +37,7 @@ public class TemporaryUrlSignerMockTest extends BaseOpenStackMockTest<SwiftApi>
    public void whenAccountApiHasKey() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(accountResponse().addHeader("X-Account-Meta-Temp-URL-Key", "mykey")));
+      server.enqueue(addCommonHeaders(accountResponse().addHeader(ACCOUNT_TEMPORARY_URL_KEY, "mykey")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
index 39f0a0f..6d26100 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
@@ -26,8 +26,9 @@ import org.testng.SkipException;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
-@Test(groups = "live")
+@Test(groups = "live", testName = "SwiftBlobIntegrationLiveTest")
 public class SwiftBlobIntegrationLiveTest extends BaseBlobIntegrationTest {
+   
    public SwiftBlobIntegrationLiveTest() {
       provider = "openstack-swift";
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
index f7b6b00..d9996bf 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
@@ -23,8 +23,9 @@ import java.util.Properties;
 import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
 import org.testng.annotations.Test;
 
-@Test(groups = "live")
+@Test(groups = "live", testName = "SwiftBlobLiveTest")
 public class SwiftBlobLiveTest extends BaseBlobLiveTest {
+
    public SwiftBlobLiveTest() {
       provider = "openstack-swift";
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
index 36fc024..9dd603f 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
@@ -23,8 +23,9 @@ import java.util.Properties;
 import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest;
 import org.testng.annotations.Test;
 
-@Test(groups = "live")
+@Test(groups = "live", testName = "SwiftBlobSignerLiveTest")
 public class SwiftBlobSignerLiveTest extends BaseBlobSignerLiveTest {
+
    public SwiftBlobSignerLiveTest() {
       provider = "openstack-swift";
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
index 4e682f8..d954867 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
@@ -24,8 +24,9 @@ import java.util.Properties;
 import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
 import org.testng.annotations.Test;
 
-@Test(groups = "live")
+@Test(groups = "live", testName = "SwiftContainerIntegrationLiveTest")
 public class SwiftContainerIntegrationLiveTest extends BaseContainerIntegrationTest {
+
    public SwiftContainerIntegrationLiveTest() {
       provider = "openstack-swift";
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
index 8f5ab6c..9bd85d6 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
@@ -23,8 +23,9 @@ import java.util.Properties;
 import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
 import org.testng.annotations.Test;
 
-@Test(groups = "live")
+@Test(groups = "live", testName = "SwiftContainerLiveTest")
 public class SwiftContainerLiveTest extends BaseContainerLiveTest {
+
    public SwiftContainerLiveTest() {
       provider = "openstack-swift";
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
index fa9a734..1da1a68 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
@@ -23,8 +23,9 @@ import java.util.Properties;
 import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest;
 import org.testng.annotations.Test;
 
-@Test(groups = "live")
+@Test(groups = "live", testName = "SwiftServiceIntegrationLiveTest")
 public class SwiftServiceIntegrationLiveTest extends BaseServiceIntegrationTest {
+
    public SwiftServiceIntegrationLiveTest() {
       provider = "openstack-swift";
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdaptersTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdaptersTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdaptersTest.java
index 30edc8f..e4225fc 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdaptersTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/config/SwiftTypeAdaptersTest.java
@@ -30,32 +30,32 @@ import com.google.gson.GsonBuilder;
 
 @Test
 public class SwiftTypeAdaptersTest {
-   Gson gson = new GsonBuilder() //
-         .registerTypeAdapter(ExtractArchiveResponse.class, new ExtractArchiveResponseAdapter()) //
-         .registerTypeAdapter(BulkDeleteResponse.class, new BulkDeleteResponseAdapter()) //
+   Gson gson = new GsonBuilder()
+         .registerTypeAdapter(ExtractArchiveResponse.class, new ExtractArchiveResponseAdapter())
+         .registerTypeAdapter(BulkDeleteResponse.class, new BulkDeleteResponseAdapter())
          .create();
 
    public void extractArchiveWithoutErrors() {
-      assertEquals(gson.fromJson("" //
-            + "{\n" //
-            + "  \"Response Status\": \"201 Created\",\n" //
-            + "  \"Response Body\": \"\",\n" //
-            + "  \"Errors\": [],\n" //
-            + "  \"Number Files Created\": 10\n" //
+      assertEquals(gson.fromJson(""
+            + "{\n"
+            + "  \"Response Status\": \"201 Created\",\n"
+            + "  \"Response Body\": \"\",\n"
+            + "  \"Errors\": [],\n"
+            + "  \"Number Files Created\": 10\n"
             + "}", ExtractArchiveResponse.class), ExtractArchiveResponse.create(10, ImmutableMap.<String, String> of()));
    }
 
    public void extractArchiveWithErrorsAndDecodesPaths() {
       assertEquals(
-            gson.fromJson("" //
-                  + "{\n" //
-                  + "  \"Response Status\": \"201 Created\",\n" //
-                  + "  \"Response Body\": \"\",\n" //
-                  + "  \"Errors\": [\n" //
-                  + "    [\"/v1/12345678912345/mycontainer/home/xx%3Cyy\", \"400 Bad Request\"],\n" //
-                  + "    [\"/v1/12345678912345/mycontainer/../image.gif\", \"400 Bad Request\"]\n" //
-                  + "  ],\n" //
-                  + "  \"Number Files Created\": 8\n" //
+            gson.fromJson(""
+                  + "{\n"
+                  + "  \"Response Status\": \"201 Created\",\n"
+                  + "  \"Response Body\": \"\",\n"
+                  + "  \"Errors\": [\n"
+                  + "    [\"/v1/12345678912345/mycontainer/home/xx%3Cyy\", \"400 Bad Request\"],\n"
+                  + "    [\"/v1/12345678912345/mycontainer/../image.gif\", \"400 Bad Request\"]\n"
+                  + "  ],\n"
+                  + "  \"Number Files Created\": 8\n"
                   + "}", ExtractArchiveResponse.class),
             ExtractArchiveResponse.create(
                   8,
@@ -65,25 +65,25 @@ public class SwiftTypeAdaptersTest {
    }
 
    public void bulkDeleteWithoutErrors() {
-      assertEquals(gson.fromJson("" //
-            + "{\n" //
-            + "  \"Response Status\": \"200 OK\",\n" //
-            + "  \"Response Body\": \"\",\n" //
-            + "  \"Errors\": [],\n" //
-            + "  \"Number Not Found\": 1,\n" //
-            + "  \"Number Deleted\": 9\n" //
+      assertEquals(gson.fromJson(""
+            + "{\n"
+            + "  \"Response Status\": \"200 OK\",\n"
+            + "  \"Response Body\": \"\",\n"
+            + "  \"Errors\": [],\n"
+            + "  \"Number Not Found\": 1,\n"
+            + "  \"Number Deleted\": 9\n"
             + "}", BulkDeleteResponse.class), BulkDeleteResponse.create(9, 1, ImmutableMap.<String, String> of()));
    }
 
    public void bulkDeleteWithErrorsAndDecodesPaths() {
-      assertEquals(gson.fromJson("" //
-            + "{\n" //
-            + "  \"Response Status\": \"400 Bad Request\",\n" //
-            + "  \"Response Body\": \"\",\n" //
-            + "  \"Errors\": [\n" //
-            + "    [\"/v1/12345678912345/Not%20Empty\", \"409 Conflict\"]" //
-            + "  ],\n" //
-            + "  \"Number Deleted\": 0\n" //
+      assertEquals(gson.fromJson(""
+            + "{\n"
+            + "  \"Response Status\": \"400 Bad Request\",\n"
+            + "  \"Response Body\": \"\",\n"
+            + "  \"Errors\": [\n"
+            + "    [\"/v1/12345678912345/Not%20Empty\", \"409 Conflict\"]"
+            + "  ],\n"
+            + "  \"Number Deleted\": 0\n"
             + "}", BulkDeleteResponse.class),
             BulkDeleteResponse.create(0, 0, ImmutableMap.of("/v1/12345678912345/Not Empty", "409 Conflict")));
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 31eff6e..4359a71 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
@@ -24,6 +24,7 @@ import static org.testng.Assert.assertTrue;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.Account;
 import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
 import org.testng.annotations.Test;
@@ -31,21 +32,21 @@ import org.testng.annotations.Test;
 import com.google.common.collect.ImmutableMap;
 
 @Test(groups = "live", testName = "AccountApiLiveTest")
-public class AccountApiLiveTest extends BaseSwiftApiLiveTest {
+public class AccountApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
 
-   public void get() throws Exception {
+   public void testGet() throws Exception {
       for (String regionId : regions) {
          AccountApi accountApi = api.accountApiInRegion(regionId);
          Account account = accountApi.get();
 
          assertNotNull(account);
-         assertTrue(account.containerCount() >= 0);
-         assertTrue(account.objectCount() >= 0);
-         assertTrue(account.bytesUsed() >= 0);
+         assertTrue(account.getContainerCount() >= 0);
+         assertTrue(account.getObjectCount() >= 0);
+         assertTrue(account.getBytesUsed() >= 0);
       }
    }
 
-   public void updateMetadata() throws Exception {
+   public void testUpdateMetadata() throws Exception {
       for (String regionId : regions) {
          AccountApi accountApi = api.accountApiInRegion(regionId);
 
@@ -57,7 +58,7 @@ public class AccountApiLiveTest extends BaseSwiftApiLiveTest {
       }
    }
 
-   public void deleteMetadata() throws Exception {
+   public void testDeleteMetadata() throws Exception {
       for (String regionId : regions) {
          AccountApi accountApi = api.accountApiInRegion(regionId);
 
@@ -70,7 +71,7 @@ public class AccountApiLiveTest extends BaseSwiftApiLiveTest {
          Account account = accountApi.get();
          for (Entry<String, String> entry : meta.entrySet()) {
             // note keys are returned in lower-case!
-            assertFalse(account.metadata().containsKey(entry.getKey().toLowerCase()));
+            assertFalse(account.getMetadata().containsKey(entry.getKey().toLowerCase()));
          }
       }
    }
@@ -79,7 +80,7 @@ public class AccountApiLiveTest extends BaseSwiftApiLiveTest {
       Account account = accountApi.get();
       for (Entry<String, String> entry : meta.entrySet()) {
          // note keys are returned in lower-case!
-         assertEquals(account.metadata().get(entry.getKey().toLowerCase()), entry.getValue(), //
+         assertEquals(account.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue(),
                account + " didn't have metadata: " + entry);
       }
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 2c5a9b2..f7e9125 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
@@ -16,6 +16,12 @@
  */
 package org.jclouds.openstack.swift.v1.features;
 
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_BYTES_USED;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_CONTAINER_COUNT;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_OBJECT_COUNT;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_REMOVE_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.ACCOUNT_TEMPORARY_URL_KEY;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
@@ -35,32 +41,31 @@ import com.squareup.okhttp.mockwebserver.RecordedRequest;
 /**
  * @author Jeremy Daggett
  */
-@Test
+@Test(groups = "unit", testName = "AccountApiMockTest")
 public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
    /** upper-cases first char, and lower-cases rest!! **/
    public void getKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(accountResponse() //
+      server.enqueue(addCommonHeaders(accountResponse()
             // note silly casing
-            .addHeader("X-Account-Meta-Apiname", "swift") //
-            .addHeader("X-Account-Meta-Apiversion", "v1.1")));
+            .addHeader(ACCOUNT_METADATA_PREFIX + "Apiname", "swift")
+            .addHeader(ACCOUNT_METADATA_PREFIX + "Apiversion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
          Account account = api.accountApiInRegion("DFW").get();
-         assertEquals(account.containerCount(), 3l);
-         assertEquals(account.objectCount(), 42l);
-         assertEquals(account.bytesUsed(), 323479l);
+         assertEquals(account.getContainerCount(), 3l);
+         assertEquals(account.getObjectCount(), 42l);
+         assertEquals(account.getBytesUsed(), 323479l);
          for (Entry<String, String> entry : metadata.entrySet()) {
-            assertEquals(account.metadata().get(entry.getKey().toLowerCase()), entry.getValue());
+            assertEquals(account.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue());
          }
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         assertEquals(server.takeRequest().getRequestLine(),
-               "HEAD /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/ HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/");
       } finally {
          server.shutdown();
       }
@@ -69,21 +74,21 @@ public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    public void updateMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
       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")));
+      server.enqueue(addCommonHeaders(accountResponse()
+            .addHeader(ACCOUNT_METADATA_PREFIX + "ApiName", "swift")
+            .addHeader(ACCOUNT_METADATA_PREFIX + "ApiVersion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
          assertTrue(api.accountApiInRegion("DFW").updateMetadata(metadata));
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+         assertAuthentication(server);
+         
          RecordedRequest replaceRequest = server.takeRequest();
-         assertEquals(replaceRequest.getRequestLine(),
-               "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/ HTTP/1.1");
+         assertRequest(replaceRequest,"POST", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/");
          for (Entry<String, String> entry : metadata.entrySet()) {
-            assertEquals(replaceRequest.getHeader("x-account-meta-" + entry.getKey().toLowerCase()), entry.getValue());
+            assertEquals(replaceRequest.getHeader(ACCOUNT_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
          }
       } finally {
          server.shutdown();
@@ -100,11 +105,11 @@ public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertTrue(api.accountApiInRegion("DFW").updateTemporaryUrlKey("foobar"));
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+         assertAuthentication(server);
+         
          RecordedRequest replaceRequest = server.takeRequest();
-         assertEquals(replaceRequest.getRequestLine(),
-               "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/ HTTP/1.1");
-         assertEquals(replaceRequest.getHeader("X-Account-Meta-Temp-URL-Key"), "foobar");
+         assertRequest(replaceRequest, "POST", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/");
+         assertEquals(replaceRequest.getHeader(ACCOUNT_TEMPORARY_URL_KEY), "foobar");
       } finally {
          server.shutdown();
       }
@@ -125,7 +130,7 @@ public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertEquals(deleteRequest.getRequestLine(),
                "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/ HTTP/1.1");
          for (String key : metadata.keySet()) {
-            assertEquals(deleteRequest.getHeader("x-remove-account-meta-" + key.toLowerCase()), "ignored");
+            assertEquals(deleteRequest.getHeader(ACCOUNT_REMOVE_METADATA_PREFIX + key.toLowerCase()), "ignored");
          }
       } finally {
          server.shutdown();
@@ -135,9 +140,9 @@ public class AccountApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
 
    public static MockResponse accountResponse() {
-      return new MockResponse() //
-            .addHeader("X-Account-Container-Count", "3") //
-            .addHeader("X-Account-Object-Count", "42") //
-            .addHeader("X-Account-Bytes-Used", "323479");
+      return new MockResponse()
+            .addHeader(ACCOUNT_CONTAINER_COUNT, "3")
+            .addHeader(ACCOUNT_OBJECT_COUNT, "42")
+            .addHeader(ACCOUNT_BYTES_USED, "323479");
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 39341fd..fa8e6b6 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
@@ -28,6 +28,7 @@ import org.jboss.shrinkwrap.api.ShrinkWrap;
 import org.jboss.shrinkwrap.api.asset.StringAsset;
 import org.jboss.shrinkwrap.api.exporter.TarGzExporter;
 import org.jclouds.io.Payloads;
+import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.BulkDeleteResponse;
 import org.jclouds.openstack.swift.v1.domain.ExtractArchiveResponse;
 import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
@@ -42,46 +43,46 @@ import com.google.common.collect.Lists;
 import com.google.common.io.ByteStreams;
 
 @Test(groups = "live", testName = "BulkApiLiveTest")
-public class BulkApiLiveTest extends BaseSwiftApiLiveTest {
+public class BulkApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
 
    static final int OBJECT_COUNT = 10;
 
    private String containerName = getClass().getSimpleName();
 
-   public void notPresentWhenDeleting() throws Exception {
+   public void testNotPresentWhenDeleting() throws Exception {
       for (String regionId : regions) {
          BulkDeleteResponse deleteResponse = api.bulkApiInRegion(regionId).bulkDelete(
                ImmutableList.of(UUID.randomUUID().toString()));
-         assertEquals(deleteResponse.deleted(), 0);
-         assertEquals(deleteResponse.notFound(), 1);
-         assertTrue(deleteResponse.errors().isEmpty());
+         assertEquals(deleteResponse.getDeleted(), 0);
+         assertEquals(deleteResponse.getNotFound(), 1);
+         assertTrue(deleteResponse.getErrors().isEmpty());
       }
    }
 
-   public void extractArchive() throws Exception {
+   public void testExtractArchive() throws Exception {
       for (String regionId : regions) {
          ExtractArchiveResponse extractResponse = api.bulkApiInRegion(regionId).extractArchive(containerName,
                Payloads.newPayload(tarGz), "tar.gz");
-         assertEquals(extractResponse.created(), OBJECT_COUNT);
-         assertTrue(extractResponse.errors().isEmpty());
-         assertEquals(api.containerApiInRegion(regionId).get(containerName).objectCount(), OBJECT_COUNT);
+         assertEquals(extractResponse.getCreated(), OBJECT_COUNT);
+         assertTrue(extractResponse.getErrors().isEmpty());
+         assertEquals(api.containerApiInRegion(regionId).get(containerName).getObjectCount(), OBJECT_COUNT);
 
          // repeat the command
          extractResponse = api.bulkApiInRegion(regionId).extractArchive(containerName, Payloads.newPayload(tarGz),
                "tar.gz");
-         assertEquals(extractResponse.created(), OBJECT_COUNT);
-         assertTrue(extractResponse.errors().isEmpty());
+         assertEquals(extractResponse.getCreated(), OBJECT_COUNT);
+         assertTrue(extractResponse.getErrors().isEmpty());
       }
    }
 
-   @Test(dependsOnMethods = "extractArchive")
-   public void bulkDelete() throws Exception {
+   @Test(dependsOnMethods = "testExtractArchive")
+   public void testBulkDelete() throws Exception {
       for (String regionId : regions) {
          BulkDeleteResponse deleteResponse = api.bulkApiInRegion(regionId).bulkDelete(paths);
-         assertEquals(deleteResponse.deleted(), OBJECT_COUNT);
-         assertEquals(deleteResponse.notFound(), 0);
-         assertTrue(deleteResponse.errors().isEmpty());
-         assertEquals(api.containerApiInRegion(regionId).get(containerName).objectCount(), 0);
+         assertEquals(deleteResponse.getDeleted(), OBJECT_COUNT);
+         assertEquals(deleteResponse.getNotFound(), 0);
+         assertTrue(deleteResponse.getErrors().isEmpty());
+         assertEquals(api.containerApiInRegion(regionId).get(containerName).getObjectCount(), 0);
       }
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 69ce5a1..5b4c200 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
@@ -34,11 +34,10 @@ import com.squareup.okhttp.mockwebserver.MockResponse;
 import com.squareup.okhttp.mockwebserver.MockWebServer;
 import com.squareup.okhttp.mockwebserver.RecordedRequest;
 
-// TODO: cannot yet test bulk delete offline
-@Test
+@Test(groups = "unit", testName = "BulkApiMockTest")
 public class BulkApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
 
-   public void extractArchive() throws Exception {
+   public void testExtractArchive() throws Exception {
       GenericArchive files = ShrinkWrap.create(GenericArchive.class, "files.tar.gz");
       StringAsset content = new StringAsset("foo");
       for (int i = 0; i < 10; i++) {
@@ -54,14 +53,13 @@ public class BulkApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
          ExtractArchiveResponse response = api.bulkApiInRegion("DFW").extractArchive("myContainer",
                newByteArrayPayload(tarGz), "tar.gz");
-         assertEquals(response.created(), 10);
-         assertTrue(response.errors().isEmpty());
+         assertEquals(response.getCreated(), 10);
+         assertTrue(response.getErrors().isEmpty());
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+         assertAuthentication(server);
          RecordedRequest extractRequest = server.takeRequest();
-         assertEquals(extractRequest.getRequestLine(),
-               "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer?extract-archive=tar.gz HTTP/1.1");
+         assertRequest(extractRequest, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer?extract-archive=tar.gz");
          assertEquals(extractRequest.getBody(), tarGz);
       } finally {
          server.shutdown();

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 e28ca8e..31ff231 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
@@ -24,9 +24,11 @@ import static org.testng.Assert.assertTrue;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.Container;
 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.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
@@ -36,71 +38,70 @@ import com.google.common.collect.ImmutableMap;
 
 /**
  * @author Adrian Cole
+ * @author Jeremy Daggett
  */
 @Test(groups = "live", testName = "ContainerApiLiveTest")
-public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
+public class ContainerApiLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
 
    private String name = getClass().getSimpleName();
 
-   @Test
-   public void list() throws Exception {
+   public void testList() throws Exception {
       for (String regionId : regions) {
          ContainerApi containerApi = api.containerApiInRegion(regionId);
-         FluentIterable<Container> response = containerApi.listFirstPage();
+         FluentIterable<Container> response = containerApi.list();
          assertNotNull(response);
          for (Container container : response) {
-            assertNotNull(container.name());
-            assertTrue(container.objectCount() >= 0);
-            assertTrue(container.bytesUsed() >= 0);
+            assertNotNull(container.getName());
+            assertTrue(container.getObjectCount() >= 0);
+            assertTrue(container.getBytesUsed() >= 0);
          }
       }
    }
 
-   public void get() throws Exception {
+   public void testListWithOptions() throws Exception {
+      String lexicographicallyBeforeName = name.substring(0, name.length() - 1);
       for (String regionId : regions) {
-         Container container = api.containerApiInRegion(regionId).get(name);
-         assertEquals(container.name(), name);
-         assertTrue(container.objectCount() == 0);
-         assertTrue(container.bytesUsed() == 0);
+         ListContainerOptions options = ListContainerOptions.Builder.marker(lexicographicallyBeforeName);
+         Container container = api.containerApiInRegion(regionId).list(options).get(0);
+         assertEquals(container.getName(), name);
+         assertTrue(container.getObjectCount() == 0);
+         assertTrue(container.getBytesUsed() == 0);
       }
    }
-
-   public void listAt() throws Exception {
-      String lexicographicallyBeforeName = name.substring(0, name.length() - 1);
+   
+   public void testGet() throws Exception {
       for (String regionId : regions) {
-         Container container = api.containerApiInRegion(regionId).listAt(lexicographicallyBeforeName).get(0);
-         assertEquals(container.name(), name);
-         assertTrue(container.objectCount() == 0);
-         assertTrue(container.bytesUsed() == 0);
+         Container container = api.containerApiInRegion(regionId).get(name);
+         assertEquals(container.getName(), name);
+         assertTrue(container.getObjectCount() == 0);
+         assertTrue(container.getBytesUsed() == 0);
       }
    }
 
-   public void updateMetadata() throws Exception {
+   public void testUpdateMetadata() throws Exception {
+      Map<String, String> meta = ImmutableMap.of("MyAdd1", "foo", "MyAdd2", "bar");
+
       for (String regionId : regions) {
          ContainerApi containerApi = api.containerApiInRegion(regionId);
-
-         Map<String, String> meta = ImmutableMap.of("MyAdd1", "foo", "MyAdd2", "bar");
-
          assertTrue(containerApi.updateMetadata(name, meta));
-
          containerHasMetadata(containerApi, name, meta);
       }
    }
 
-   public void deleteMetadata() throws Exception {
+   public void testDeleteMetadata() throws Exception {
+      Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");
+
       for (String regionId : regions) {
          ContainerApi containerApi = api.containerApiInRegion(regionId);
-
-         Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");
-
+         // update
          assertTrue(containerApi.updateMetadata(name, meta));
          containerHasMetadata(containerApi, name, meta);
-
+         // delete
          assertTrue(containerApi.deleteMetadata(name, meta));
          Container container = containerApi.get(name);
          for (Entry<String, String> entry : meta.entrySet()) {
             // note keys are returned in lower-case!
-            assertFalse(container.metadata().containsKey(entry.getKey().toLowerCase()));
+            assertFalse(container.getMetadata().containsKey(entry.getKey().toLowerCase()));
          }
       }
    }
@@ -109,7 +110,7 @@ public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
       Container container = containerApi.get(name);
       for (Entry<String, String> entry : meta.entrySet()) {
          // note keys are returned in lower-case!
-         assertEquals(container.metadata().get(entry.getKey().toLowerCase()), entry.getValue(), //
+         assertEquals(container.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue(),
                container + " didn't have metadata: " + entry);
       }
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/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 b52122d..752b4b7 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
@@ -17,8 +17,15 @@
 package org.jclouds.openstack.swift.v1.features;
 
 import static org.jclouds.openstack.swift.v1.options.CreateContainerOptions.Builder.anybodyRead;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_ACL_ANYBODY_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_BYTES_USED;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_METADATA_PREFIX;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_OBJECT_COUNT;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_READ;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.CONTAINER_REMOVE_METADATA_PREFIX;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 import java.util.Map;
@@ -26,8 +33,9 @@ import java.util.Map.Entry;
 
 import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.Container;
-import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
 import org.jclouds.openstack.swift.v1.options.CreateContainerOptions;
+import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
+import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest;
 import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
@@ -36,70 +44,65 @@ import com.squareup.okhttp.mockwebserver.MockResponse;
 import com.squareup.okhttp.mockwebserver.MockWebServer;
 import com.squareup.okhttp.mockwebserver.RecordedRequest;
 
-@Test
+@Test(groups = "unit", testName = "ContainerApiMockTest")
 public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
-
-   String containerList = "" //
-         + "[\n" //
-         + "  {\"name\":\"test_container_1\", \"count\":2, \"bytes\":78},\n" //
-         + "  {\"name\":\"test_container_2\", \"count\":1, \"bytes\":17}\n" //
-         + "]";
-
-   public void listFirstPage() throws Exception {
+   
+   public void testList() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(new MockResponse().setBody(containerList)));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/container_list.json"))));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
-         ImmutableList<Container> containers = api.containerApiInRegion("DFW").listFirstPage().toList();
-         assertEquals(containers, ImmutableList.of(//
-               Container.builder() //
-                     .name("test_container_1") //
-                     .objectCount(2) //
-                     .bytesUsed(78).build(), //
-               Container.builder() //
-                     .name("test_container_2") //
-                     .objectCount(1) //
+         ImmutableList<Container> containers = api.containerApiInRegion("DFW").list().toList();
+         assertEquals(containers, ImmutableList.of(
+               Container.builder()
+                     .name("test_container_1")
+                     .objectCount(2)
+                     .bytesUsed(78).build(),
+               Container.builder()
+                     .name("test_container_2")
+                     .objectCount(1)
                      .bytesUsed(17).build()));
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         assertEquals(server.takeRequest().getRequestLine(),
-               "GET /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/?format=json HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/?format=json");
       } finally {
          server.shutdown();
       }
    }
 
-   public void listAt() throws Exception {
+   public void testListWithOptions() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(new MockResponse().setBody(containerList)));
+      server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/container_list.json"))));
 
+      ListContainerOptions options = ListContainerOptions.Builder.marker("test");
+      assertNotNull(options);
+      
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
-         ImmutableList<Container> containers = api.containerApiInRegion("DFW").listAt("test").toList();
-         assertEquals(containers, ImmutableList.of(//
-               Container.builder() //
-                     .name("test_container_1") //
-                     .objectCount(2) //
-                     .bytesUsed(78).build(), //
-               Container.builder() //
-                     .name("test_container_2") //
-                     .objectCount(1) //
+         ImmutableList<Container> containers = api.containerApiInRegion("DFW").list(options).toList();
+         assertEquals(containers, ImmutableList.of(
+               Container.builder()
+                     .name("test_container_1")
+                     .objectCount(2)
+                     .bytesUsed(78).build(),
+               Container.builder()
+                     .name("test_container_2")
+                     .objectCount(1)
                      .bytesUsed(17).build()));
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         assertEquals(server.takeRequest().getRequestLine(),
-               "GET /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/?format=json&marker=test HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "GET", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/?format=json&marker=test");
       } finally {
          server.shutdown();
       }
    }
 
-   public void createIfAbsent() throws Exception {
+   public void testCreateIfAbsent() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
@@ -109,16 +112,14 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertTrue(api.containerApiInRegion("DFW").createIfAbsent("myContainer", CreateContainerOptions.NONE));
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         RecordedRequest createRequest = server.takeRequest();
-         assertEquals(createRequest.getRequestLine(),
-               "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
       } finally {
          server.shutdown();
       }
    }
 
-   public void createWithOptions() throws Exception {
+   public void testCreateWithOptions() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(201)));
@@ -128,20 +129,22 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertTrue(api.containerApiInRegion("DFW").createIfAbsent("myContainer", anybodyRead().metadata(metadata)));
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+         assertAuthentication(server);
+
          RecordedRequest createRequest = server.takeRequest();
-         assertEquals(createRequest.getRequestLine(),
-               "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
-         assertEquals(createRequest.getHeader("x-container-read"), ".r:*,.rlistings");
+         assertRequest(createRequest, "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
+         
+         assertEquals(createRequest.getHeader(CONTAINER_READ), CONTAINER_ACL_ANYBODY_READ);
+         
          for (Entry<String, String> entry : metadata.entrySet()) {
-            assertEquals(createRequest.getHeader("x-container-meta-" + entry.getKey().toLowerCase()), entry.getValue());
+            assertEquals(createRequest.getHeader(CONTAINER_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
          }
       } finally {
          server.shutdown();
       }
    }
 
-   public void alreadyCreated() throws Exception {
+   public void testAlreadyCreated() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
       server.enqueue(addCommonHeaders(new MockResponse().setResponseCode(202)));
@@ -151,38 +154,35 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertFalse(api.containerApiInRegion("DFW").createIfAbsent("myContainer", CreateContainerOptions.NONE));
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         RecordedRequest createRequest = server.takeRequest();
-         assertEquals(createRequest.getRequestLine(),
-               "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "PUT", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
       } finally {
          server.shutdown();
       }
    }
 
    /** upper-cases first char, and lower-cases rest!! **/
-   public void getKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
+   public void testGetKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
       MockWebServer server = mockOpenStackServer();
       server.enqueue(addCommonHeaders(new MockResponse().setBody(stringFromResource("/access.json"))));
-      server.enqueue(addCommonHeaders(containerResponse() //
+      server.enqueue(addCommonHeaders(containerResponse()
             // note silly casing
-            .addHeader("X-Container-Meta-Apiname", "swift") //
-            .addHeader("X-Container-Meta-Apiversion", "v1.1")));
+            .addHeader(CONTAINER_METADATA_PREFIX + "Apiname", "swift")
+            .addHeader(CONTAINER_METADATA_PREFIX + "Apiversion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
          Container container = api.containerApiInRegion("DFW").get("myContainer");
-         assertEquals(container.name(), "myContainer");
-         assertEquals(container.objectCount(), 42l);
-         assertEquals(container.bytesUsed(), 323479l);
-         for (Entry<String, String> entry : container.metadata().entrySet()) {
-            assertEquals(container.metadata().get(entry.getKey().toLowerCase()), entry.getValue());
+         assertEquals(container.getName(), "myContainer");
+         assertEquals(container.getObjectCount(), 42l);
+         assertEquals(container.getBytesUsed(), 323479l);
+         for (Entry<String, String> entry : container.getMetadata().entrySet()) {
+            assertEquals(container.getMetadata().get(entry.getKey().toLowerCase()), entry.getValue());
          }
 
          assertEquals(server.getRequestCount(), 2);
-         assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
-         assertEquals(server.takeRequest().getRequestLine(),
-               "HEAD /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+         assertAuthentication(server);
+         assertRequest(server.takeRequest(), "HEAD", "/v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer");
       } finally {
          server.shutdown();
       }
@@ -191,9 +191,9 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    public void updateMetadata() throws Exception {
       MockWebServer server = mockOpenStackServer();
       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")));
+      server.enqueue(addCommonHeaders(containerResponse()
+            .addHeader(CONTAINER_METADATA_PREFIX + "ApiName", "swift")
+            .addHeader(CONTAINER_METADATA_PREFIX + "ApiVersion", "v1.1")));
 
       try {
          SwiftApi api = api(server.getUrl("/").toString(), "openstack-swift");
@@ -205,7 +205,7 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertEquals(replaceRequest.getRequestLine(),
                "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
          for (Entry<String, String> entry : metadata.entrySet()) {
-            assertEquals(replaceRequest.getHeader("x-container-meta-" + entry.getKey().toLowerCase()), entry.getValue());
+            assertEquals(replaceRequest.getHeader(CONTAINER_METADATA_PREFIX + entry.getKey().toLowerCase()), entry.getValue());
          }
       } finally {
          server.shutdown();
@@ -227,7 +227,7 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
          assertEquals(deleteRequest.getRequestLine(),
                "POST /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
          for (String key : metadata.keySet()) {
-            assertEquals(deleteRequest.getHeader("x-remove-container-meta-" + key.toLowerCase()), "ignored");
+            assertEquals(deleteRequest.getHeader(CONTAINER_REMOVE_METADATA_PREFIX + key.toLowerCase()), "ignored");
          }
       } finally {
          server.shutdown();
@@ -295,8 +295,8 @@ public class ContainerApiMockTest extends BaseOpenStackMockTest<SwiftApi> {
    private static final Map<String, String> metadata = ImmutableMap.of("ApiName", "swift", "ApiVersion", "v1.1");
 
    public static MockResponse containerResponse() {
-      return new MockResponse() //
-            .addHeader("X-Container-Object-Count", "42") //
-            .addHeader("X-Container-Bytes-Used", "323479");
+      return new MockResponse()
+            .addHeader(CONTAINER_OBJECT_COUNT, "42")
+            .addHeader(CONTAINER_BYTES_USED, "323479");
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-openstack/blob/43aa5b3a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.java
index f6251d0..6f921ef 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.java
@@ -19,19 +19,20 @@ package org.jclouds.openstack.swift.v1.features;
 import static org.jclouds.openstack.swift.v1.options.CreateContainerOptions.Builder.anybodyRead;
 import static org.testng.Assert.assertTrue;
 
+import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.Test;
 
 @Test(groups = "live", testName = "CreatePublicContainerLiveTest")
-public class CreatePublicContainerLiveTest extends BaseSwiftApiLiveTest {
+public class CreatePublicContainerLiveTest extends BaseSwiftApiLiveTest<SwiftApi> {
 
    private String name = getClass().getSimpleName();
 
-   public void anybodyReadUpdatesMetadata() throws Exception {
+   public void testAnybodyReadUpdatesMetadata() throws Exception {
       for (String regionId : api.configuredRegions()) {
          api.containerApiInRegion(regionId).createIfAbsent(name, anybodyRead());
-         assertTrue(api.containerApiInRegion(regionId).get(name).anybodyRead().get());
+         assertTrue(api.containerApiInRegion(regionId).get(name).getAnybodyRead().get());
       }
    }