You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ad...@apache.org on 2013/09/28 16:16:16 UTC
[1/3] git commit: JCLOUDS-306. refactored and completed swift
ContainerApi
Updated Branches:
refs/heads/master f46c86a97 -> f5e4012f9
JCLOUDS-306. refactored and completed swift ContainerApi
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/commit/f5e4012f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/f5e4012f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/f5e4012f
Branch: refs/heads/master
Commit: f5e4012f9e88b6cedfda5b61c760ef363ad7e772
Parents: f867518
Author: Adrian Cole <ad...@gmail.com>
Authored: Fri Sep 27 21:38:00 2013 -0700
Committer: Adrian Cole <ad...@gmail.com>
Committed: Sat Sep 28 07:12:01 2013 -0700
----------------------------------------------------------------------
.../openstack/swift/v1/domain/Container.java | 52 +++-
.../swift/v1/features/ContainerApi.java | 142 +++++++++-
.../swift/v1/functions/FalseOnAccepted.java | 30 ++
.../v1/functions/ParseContainerFromHeaders.java | 46 +++
.../swift/v1/handlers/SwiftErrorHandler.java | 3 +
.../swift/v1/options/ListContainersOptions.java | 77 -----
.../swift/v1/features/ContainerApiLiveTest.java | 90 +++++-
.../swift/v1/features/ContainerApiMockTest.java | 280 +++++++++++++++++++
.../v1/options/ListContainersOptionsTest.java | 92 ------
.../swift/v1/parse/ParseContainerListTest.java | 56 ----
.../src/test/resources/container_list.json | 4 -
11 files changed, 623 insertions(+), 249 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/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 612aa80..cfee278 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
@@ -21,9 +21,14 @@ import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jclouds.openstack.swift.v1.features.ContainerApi;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.collect.ImmutableMap;
/**
* @see <a
@@ -35,12 +40,14 @@ public class Container implements Comparable<Container> {
private final String name;
private final long objectCount;
private final long bytesUsed;
+ private final Map<String, String> metadata;
- @ConstructorProperties({ "name", "count", "bytes" })
- protected Container(String name, long objectCount, long bytesUsed) {
+ @ConstructorProperties({ "name", "count", "bytes", "metadata" })
+ protected Container(String name, long objectCount, long bytesUsed, Map<String, String> metadata) {
this.name = checkNotNull(name, "name");
this.objectCount = objectCount;
this.bytesUsed = bytesUsed;
+ this.metadata = metadata == null ? ImmutableMap.<String, String> of() : metadata;
}
public String name() {
@@ -55,6 +62,18 @@ public class Container implements Comparable<Container> {
return bytesUsed;
}
+ /**
+ * Empty except in {@link ContainerApi#get(String) GetContainer} commands.
+ *
+ * <h3>Note</h3>
+ *
+ * In current swift implementations, headers keys are lower-cased. This means
+ * characters such as turkish will probably not work out well.
+ */
+ public Map<String, String> metadata() {
+ return metadata;
+ }
+
@Override
public boolean equals(Object object) {
if (this == object) {
@@ -64,7 +83,8 @@ public class Container implements Comparable<Container> {
final Container that = Container.class.cast(object);
return equal(name(), that.name()) //
&& equal(objectCount(), that.objectCount()) //
- && equal(bytesUsed(), that.bytesUsed());
+ && equal(bytesUsed(), that.bytesUsed()) //
+ && equal(metadata(), that.metadata());
} else {
return false;
}
@@ -72,7 +92,7 @@ public class Container implements Comparable<Container> {
@Override
public int hashCode() {
- return Objects.hashCode(name(), objectCount(), bytesUsed());
+ return Objects.hashCode(name(), objectCount(), bytesUsed(), metadata());
}
@Override
@@ -84,7 +104,8 @@ public class Container implements Comparable<Container> {
return toStringHelper("") //
.add("name", name()) //
.add("objectCount", objectCount()) //
- .add("bytesUsed", bytesUsed());
+ .add("bytesUsed", bytesUsed()) //
+ .add("metadata", metadata());
}
@Override
@@ -108,6 +129,7 @@ public class Container implements Comparable<Container> {
protected String name;
protected long objectCount;
protected long bytesUsed;
+ protected Map<String, String> metadata = ImmutableMap.of();
/**
* @see Container#name()
@@ -133,14 +155,30 @@ public class Container implements Comparable<Container> {
return this;
}
+ /**
+ * Will lower-case all metadata keys due to a swift implementation
+ * decision.
+ *
+ * @see Container#metadata()
+ */
+ public Builder metadata(Map<String, String> metadata) {
+ ImmutableMap.Builder<String, String> builder = ImmutableMap.<String, String> builder();
+ for (Entry<String, String> entry : checkNotNull(metadata, "metadata").entrySet()) {
+ builder.put(entry.getKey().toLowerCase(), entry.getValue());
+ }
+ this.metadata = builder.build();
+ return this;
+ }
+
public Container build() {
- return new Container(name, objectCount, bytesUsed);
+ return new Container(name, objectCount, bytesUsed, metadata);
}
public Builder fromContainer(Container from) {
return name(from.name()) //
.objectCount(from.objectCount()) //
- .bytesUsed(from.bytesUsed());
+ .bytesUsed(from.bytesUsed()) //
+ .metadata(from.metadata());
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/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 5696d77..a1b7ae7 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
@@ -16,17 +16,36 @@
*/
package org.jclouds.openstack.swift.v1.features;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
+import java.util.Map;
+
+import javax.inject.Named;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
-import javax.ws.rs.core.MediaType;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.QueryParam;
+
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.binders.BindMetadataToHeaders.BindContainerMetadataToHeaders;
+import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveContainerMetadataToHeaders;
import org.jclouds.openstack.swift.v1.domain.Container;
-import org.jclouds.openstack.swift.v1.options.ListContainersOptions;
+import org.jclouds.openstack.swift.v1.functions.FalseOnAccepted;
+import org.jclouds.openstack.swift.v1.functions.ParseContainerFromHeaders;
+import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
import com.google.common.collect.FluentIterable;
@@ -40,31 +59,132 @@ import com.google.common.collect.FluentIterable;
* >api doc</a>
*/
@RequestFilters(AuthenticateRequest.class)
+@Consumes(APPLICATION_JSON)
public interface ContainerApi {
/**
- * @see #list(ListContainersOptions)
+ * Lists up to 10,000 containers.
+ *
+ * @return a list of existing storage containers ordered by name.
*/
+ @Named("ListContainers")
@GET
- @Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
@Path("/")
- FluentIterable<? extends Container> list();
+ FluentIterable<Container> listFirstPage();
/**
- * retrieve a list of existing storage containers ordered by name. The sort order for the name is
- * based on a binary comparison, a single built-in collating sequence that compares string data
- * using SQLite's memcmp() function, regardless of text encoding.
+ * Lists up to 10,000 containers, starting at {@code marker}
+ *
+ * @param marker
+ * lexicographic position to start list.
*
- * @param options
* @return a list of existing storage containers ordered by name.
*/
+ @Named("ListContainers")
@GET
- @Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
@Path("/")
- FluentIterable<? extends Container> list(ListContainersOptions options);
+ FluentIterable<Container> listAt(@QueryParam("marker") String marker);
+
+ /**
+ * Creates a container, if not already present.
+ *
+ * @param containerName
+ * corresponds to {@link Container#name()}.
+ * @see <a
+ * href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/create-container.html">
+ * Create Container API</a>
+ *
+ * @return <code>false</code> if the container already existed.
+ */
+ @Named("CreateContainer")
+ @PUT
+ @ResponseParser(FalseOnAccepted.class)
+ @Path("/{containerName}")
+ boolean createIfAbsent(@PathParam("containerName") String containerName);
+
+ /**
+ * Gets the {@link Container}.
+ *
+ * @param containerName
+ * corresponds to {@link Container#name()}.
+ * @return the Container or null, if not found.
+ *
+ * @see <a
+ * href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/retrieve-Container-metadata.html">
+ * Get Container Metadata API</a>
+ */
+ @Named("GetContainer")
+ @HEAD
+ @ResponseParser(ParseContainerFromHeaders.class)
+ @Fallback(NullOnNotFoundOr404.class)
+ @Path("/{containerName}")
+ @Nullable
+ Container get(@PathParam("containerName") String containerName);
+ /**
+ * Creates or updates the Container metadata.
+ *
+ * @param containerName
+ * corresponds to {@link Container#name()}.
+ * @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>
+ *
+ * @return <code>true</code> if the Container Metadata was successfully
+ * created or updated, false if not.
+ */
+ @Named("UpdateContainerMetadata")
+ @POST
+ @Fallback(FalseOnNotFoundOr404.class)
+ @Path("/{containerName}")
+ boolean updateMetadata(@PathParam("containerName") String containerName,
+ @BinderParam(BindContainerMetadataToHeaders.class) Map<String, String> metadata);
+
+ /**
+ * Deletes Container metadata.
+ *
+ * @param containerName
+ * corresponds to {@link Container#name()}.
+ * @param metadata
+ * 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>
+ */
+ @Named("DeleteContainerMetadata")
+ @POST
+ @Fallback(FalseOnNotFoundOr404.class)
+ @Path("/{containerName}")
+ boolean deleteMetadata(@PathParam("containerName") String containerName,
+ @BinderParam(BindRemoveContainerMetadataToHeaders.class) Map<String, String> metadata);
+
+ /**
+ * Deletes a 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>
+ *
+ * @return <code>false</code> if the container was not present.
+ * @throws IllegalStateException
+ * when the container wasn't empty.
+ */
+ @Named("DeleteContainer")
+ @DELETE
+ @Fallback(FalseOnNotFoundOr404.class)
+ @Path("/{containerName}")
+ boolean deleteIfEmpty(@PathParam("containerName") String containerName) throws IllegalStateException;
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/FalseOnAccepted.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/FalseOnAccepted.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/FalseOnAccepted.java
new file mode 100644
index 0000000..68da524
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/FalseOnAccepted.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.openstack.swift.v1.functions;
+
+import org.jclouds.http.HttpResponse;
+
+import com.google.common.base.Function;
+
+/** Returns {@code false} on HTTP 202 {@code Accepted}. */
+public class FalseOnAccepted implements Function<HttpResponse, Boolean> {
+
+ @Override
+ public Boolean apply(HttpResponse from) {
+ return from.getStatusCode() == 202 ? false : true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/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
new file mode 100644
index 0000000..5e66202
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.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.functions;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.openstack.swift.v1.domain.Container;
+import org.jclouds.rest.InvocationContext;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
+
+import com.google.common.base.Function;
+
+public class ParseContainerFromHeaders implements Function<HttpResponse, Container>,
+ InvocationContext<ParseContainerFromHeaders> {
+
+ private String name;
+
+ @Override
+ public Container apply(HttpResponse from) {
+ return Container.builder() //
+ .name(name) //
+ .bytesUsed(Long.parseLong(from.getFirstHeaderOrNull("X-Container-Bytes-Used"))) //
+ .objectCount(Integer.parseInt(from.getFirstHeaderOrNull("X-Container-Object-Count"))) //
+ .metadata(EntriesWithoutMetaPrefix.INSTANCE.apply(from.getHeaders())).build();
+ }
+
+ @Override
+ public ParseContainerFromHeaders setContext(HttpRequest request) {
+ this.name = GeneratedHttpRequest.class.cast(request).getInvocation().getArgs().get(0).toString();
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/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 e71daa6..f94f4a8 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
@@ -65,6 +65,9 @@ public class SwiftErrorHandler implements HttpErrorHandler {
}
}
break;
+ case 409:
+ exception = new IllegalStateException(exception.getMessage(), exception);
+ break;
}
command.setException(exception);
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java
deleted file mode 100644
index 2efa90b..0000000
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/ListContainersOptions.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.openstack.swift.v1.options;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import org.jclouds.http.options.BaseHttpRequestOptions;
-
-/**
- * Contains options supported in the REST API for the GET container operation. <h2>
- */
-public class ListContainersOptions extends BaseHttpRequestOptions {
- public static final ListContainersOptions NONE = new ListContainersOptions();
-
- /**
- * Given a string value x, return object names greater in value than the specified marker.
- */
- public ListContainersOptions marker(String marker) {
- queryParameters.put("marker", checkNotNull(marker, "marker"));
- return this;
- }
-
- public String getMarker() {
- return getFirstQueryOrNull("marker");
- }
-
- /**
- * For an integer value n, limits the number of results to n values.
- */
- public ListContainersOptions limit(int limit) {
- checkState(limit >= 0, "limit must be >= 0");
- checkState(limit <= 10000, "limit must be <= 10000");
- queryParameters.put("limit", Integer.toString(limit));
- return this;
- }
-
- public int getLimit() {
- String val = getFirstQueryOrNull("limit");
- return val != null ? Integer.valueOf(val) : 10000;
- }
-
-
- public static class Builder {
-
- /**
- * @see ListContainersOptions#marker(String)
- */
- public static ListContainersOptions marker(String marker) {
- ListContainersOptions options = new ListContainersOptions();
- return options.marker(marker);
- }
-
- /**
- * @see ListContainersOptions#limit(int)
- */
- public static ListContainersOptions limit(int limit) {
- ListContainersOptions options = new ListContainersOptions();
- return options.limit(limit);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/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 93b248e..973d363 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
@@ -16,14 +16,22 @@
*/
package org.jclouds.openstack.swift.v1.features;
+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;
+import java.util.Map.Entry;
+
import org.jclouds.openstack.swift.v1.domain.Container;
import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
/**
* @author Adrian Cole
@@ -31,11 +39,13 @@ import com.google.common.collect.FluentIterable;
@Test(groups = "live", testName = "ContainerApiLiveTest")
public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
+ private String name = getClass().getSimpleName();
+
@Test
- public void testListContainers() throws Exception {
+ public void list() throws Exception {
for (String regionId : api.configuredRegions()) {
ContainerApi containerApi = api.containerApiInRegion(regionId);
- FluentIterable<? extends Container> response = containerApi.list();
+ FluentIterable<Container> response = containerApi.listFirstPage();
assertNotNull(response);
for (Container container : response) {
assertNotNull(container.name());
@@ -44,4 +54,80 @@ public class ContainerApiLiveTest extends BaseSwiftApiLiveTest {
}
}
}
+
+ public void get() throws Exception {
+ for (String regionId : api.configuredRegions()) {
+ Container container = api.containerApiInRegion(regionId).get(name);
+ assertEquals(container.name(), name);
+ assertTrue(container.objectCount() == 0);
+ assertTrue(container.bytesUsed() == 0);
+ }
+ }
+
+ public void listAt() throws Exception {
+ String lexicographicallyBeforeName = name.substring(0, name.length() - 1);
+ for (String regionId : api.configuredRegions()) {
+ Container container = api.containerApiInRegion(regionId).listAt(lexicographicallyBeforeName).get(0);
+ assertEquals(container.name(), name);
+ assertTrue(container.objectCount() == 0);
+ assertTrue(container.bytesUsed() == 0);
+ }
+ }
+
+ public void updateMetadata() throws Exception {
+ for (String regionId : api.configuredRegions()) {
+ 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 {
+ for (String regionId : api.configuredRegions()) {
+ ContainerApi containerApi = api.containerApiInRegion(regionId);
+
+ Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");
+
+ assertTrue(containerApi.updateMetadata(name, meta));
+ containerHasMetadata(containerApi, name, meta);
+
+ 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()));
+ }
+ }
+ }
+
+ static void containerHasMetadata(ContainerApi containerApi, String name, Map<String, String> meta) {
+ 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(), //
+ container + " didn't have metadata: " + entry);
+ }
+ }
+
+ @Override
+ @BeforeClass(groups = "live")
+ public void setup() {
+ super.setup();
+ for (String regionId : api.configuredRegions()) {
+ api.containerApiInRegion(regionId).createIfAbsent(name);
+ }
+ }
+
+ @Override
+ @AfterClass(groups = "live")
+ public void tearDown() {
+ for (String regionId : api.configuredRegions()) {
+ api.containerApiInRegion(regionId).deleteIfEmpty(name);
+ }
+ super.tearDown();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/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
new file mode 100644
index 0000000..d54530e
--- /dev/null
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ContainerApiMockTest.java
@@ -0,0 +1,280 @@
+/*
+ * 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.features;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+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.BaseSwiftMockTest;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+import com.squareup.okhttp.mockwebserver.RecordedRequest;
+
+/**
+ * @author Adrian Cole
+ */
+@Test
+public class ContainerApiMockTest extends BaseSwiftMockTest {
+
+ 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 {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(new MockResponse().setBody(containerList));
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ 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) //
+ .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");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void listAt() throws Exception {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(new MockResponse().setBody(containerList));
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ 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) //
+ .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");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void createIfAbsent() throws Exception {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(new MockResponse().setResponseCode(201));
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ assertTrue(api.containerApiInRegion("DFW").createIfAbsent("myContainer"));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void alreadyCreated() throws Exception {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(new MockResponse().setResponseCode(202));
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ assertFalse(api.containerApiInRegion("DFW").createIfAbsent("myContainer"));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ assertEquals(deleteRequest.getRequestLine(),
+ "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ /** upper-cases first char, and lower-cases rest!! **/
+ public void getKnowingServerMessesWithMetadataKeyCaseFormat() throws Exception {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(containerResponse() //
+ // note silly casing
+ .addHeader("X-Container-Meta-Apiname", "swift") //
+ .addHeader("X-Container-Meta-Apiversion", "v1.1"));
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ 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(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");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void updateMetadata() throws Exception {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(containerResponse() //
+ .addHeader("X-Container-Meta-ApiName", "swift") //
+ .addHeader("X-Container-Meta-ApiVersion", "v1.1"));
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ assertTrue(api.containerApiInRegion("DFW").updateMetadata("myContainer", metadata));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest replaceRequest = server.takeRequest();
+ 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());
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void deleteMetadata() throws Exception {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(containerResponse());
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ assertTrue(api.containerApiInRegion("DFW").deleteMetadata("myContainer", metadata));
+
+ assertEquals(server.getRequestCount(), 2);
+ assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
+ RecordedRequest deleteRequest = server.takeRequest();
+ 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");
+ }
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void deleteIfEmpty() throws Exception {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(new MockResponse().setResponseCode(204));
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ assertTrue(api.containerApiInRegion("DFW").deleteIfEmpty("myContainer"));
+
+ 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 HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ public void alreadyDeleted() throws Exception {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(new MockResponse().setResponseCode(404));
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ assertFalse(api.containerApiInRegion("DFW").deleteIfEmpty("myContainer"));
+
+ 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 HTTP/1.1");
+ } finally {
+ server.shutdown();
+ }
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void deleteWhenNotEmpty() throws Exception {
+ MockWebServer server = mockSwiftServer();
+ server.enqueue(new MockResponse().setBody(access));
+ server.enqueue(new MockResponse().setResponseCode(409));
+
+ try {
+ SwiftApi api = swiftApi(server.getUrl("/").toString());
+ api.containerApiInRegion("DFW").deleteIfEmpty("myContainer");
+
+ } finally {
+ 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 HTTP/1.1");
+ server.shutdown();
+ }
+ }
+
+ private final static 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");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java
deleted file mode 100644
index df9d4d6..0000000
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/options/ListContainersOptionsTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.openstack.swift.v1.options;
-
-import static org.jclouds.openstack.swift.v1.options.ListContainersOptions.Builder.limit;
-import static org.jclouds.openstack.swift.v1.options.ListContainersOptions.Builder.marker;
-import static org.testng.Assert.assertEquals;
-
-import com.google.common.collect.ImmutableList;
-
-import org.jclouds.http.options.HttpRequestOptions;
-import org.testng.annotations.Test;
-
-/**
- * @author Adrian Cole
- */
-@Test(testName = "ListContainersOptionsTest")
-public class ListContainersOptionsTest {
-
- @Test
- public void testAssignability() {
- assert HttpRequestOptions.class.isAssignableFrom(ListContainersOptions.class);
- assert !String.class.isAssignableFrom(ListContainersOptions.class);
- }
- @Test
- public void testNoOptionsQueryString() {
- HttpRequestOptions options = new ListContainersOptions();
- assertEquals(options.buildQueryParameters().size(), 0);
- }
-
- @Test
- public void testMarker() {
- ListContainersOptions options = new ListContainersOptions();
- options.marker("test");
- assertEquals(options.buildQueryParameters().get("marker"), ImmutableList.of("test"));
- }
-
- @Test
- public void testNullMarker() {
- ListContainersOptions options = new ListContainersOptions();
- assertEquals(options.buildQueryParameters().get("marker"), ImmutableList.of());
- }
-
- @Test
- public void testMarkerStatic() {
- ListContainersOptions options = marker("test");
- assertEquals(options.buildQueryParameters().get("marker"), ImmutableList.of("test"));
- }
-
- @Test(expectedExceptions = NullPointerException.class)
- public void testMarkerNPE() {
- marker(null);
- }
-
- @Test
- public void testLimit() {
- ListContainersOptions options = new ListContainersOptions();
- options.limit(1000);
- assertEquals(options.buildQueryParameters().get("limit"), ImmutableList.of("1000"));
- }
-
- @Test
- public void testNullLimit() {
- ListContainersOptions options = new ListContainersOptions();
- assertEquals(options.buildQueryParameters().get("limit"), ImmutableList.of());
- }
-
- @Test
- public void testLimitStatic() {
- ListContainersOptions options = limit(1000);
- assertEquals(options.buildQueryParameters().get("limit"), ImmutableList.of("1000"));
- }
-
- @Test(expectedExceptions = IllegalStateException.class)
- public void testLimitNegative() {
- limit(-1);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java
deleted file mode 100644
index 4101fb2..0000000
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/parse/ParseContainerListTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.openstack.swift.v1.parse;
-
-import java.util.Set;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.json.BaseSetParserTest;
-import org.jclouds.openstack.swift.v1.domain.Container;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableSet;
-
-/**
- * @author Adrian Cole
- */
-@Test(groups = "unit", testName = "ParseContainerListTest")
-public class ParseContainerListTest extends BaseSetParserTest<Container> {
-
- @Override
- public String resource() {
- return "/container_list.json";
- }
-
- @Override
- @Consumes(MediaType.APPLICATION_JSON)
- public Set<Container> expected() {
- return ImmutableSet
- .of(Container.builder()
- .name("test_container_1")
- .objectCount(2)
- .bytesUsed(78)
- .build(),
- Container.builder()
- .name("test_container_2")
- .objectCount(1)
- .bytesUsed(17)
- .build());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f5e4012f/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
deleted file mode 100644
index f7d9b9b..0000000
--- a/openstack-swift/src/test/resources/container_list.json
+++ /dev/null
@@ -1,4 +0,0 @@
-[
- {"name":"test_container_1", "count":2, "bytes":78},
- {"name":"test_container_2", "count":1, "bytes":17}
-]
\ No newline at end of file
[2/3] git commit: JCLOUDS-306. refactored AccountApi to be usable
from container
Posted by ad...@apache.org.
JCLOUDS-306. refactored AccountApi to be usable from container
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/commit/f867518d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/f867518d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/f867518d
Branch: refs/heads/master
Commit: f867518d6d43f2fd61df23cec6bb21fdd9e8b4e7
Parents: 4902919
Author: Adrian Cole <ad...@gmail.com>
Authored: Fri Sep 27 21:36:43 2013 -0700
Committer: Adrian Cole <ad...@gmail.com>
Committed: Sat Sep 28 07:12:01 2013 -0700
----------------------------------------------------------------------
.../binders/BindAccountMetadataToHeaders.java | 92 --------------
.../swift/v1/binders/BindMetadataToHeaders.java | 124 +++++++++++++++++++
.../openstack/swift/v1/features/AccountApi.java | 20 +--
.../swift/v1/features/AccountApiLiveTest.java | 6 +-
.../swift/v1/features/AccountApiMockTest.java | 12 +-
5 files changed, 145 insertions(+), 109 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f867518d/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindAccountMetadataToHeaders.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindAccountMetadataToHeaders.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindAccountMetadataToHeaders.java
deleted file mode 100644
index 96e58bc..0000000
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindAccountMetadataToHeaders.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.openstack.swift.v1.binders;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.jclouds.http.HttpRequest;
-import org.jclouds.rest.Binder;
-
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableMultimap.Builder;
-
-/**
- * Will lower-case header keys due to a swift implementation to return headers
- * in a different case than sent. ex.
- *
- * <pre>
- * >> X-Account-Meta-MyDelete1: foo
- * >> X-Account-Meta-MyDelete2: bar
- * </pre>
- *
- * results in:
- *
- * <pre>
- * << X-Account-Meta-Mydelete1: foo
- * << X-Account-Meta-Mydelete2: bar
- * </pre>
- *
- * <h4>Note</h4> <br/>
- * 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 BindAccountMetadataToHeaders implements Binder {
-
- private static final String ACCOUNT_METADATA_PREFIX = "x-account-meta-";
-
- @SuppressWarnings("unchecked")
- @Override
- public <R extends HttpRequest> R bindToRequest(R request, Object input) {
- checkNotNull(request, "request");
- checkArgument(input instanceof Map<?, ?>, "input must be a non-null java.util.Map!");
- Map<String, String> metadata = Map.class.cast(input);
- Builder<String, String> headers = ImmutableMultimap.<String, String> builder();
- for (Entry<String, String> keyVal : metadata.entrySet()) {
- String keyInLowercase = keyVal.getKey().toLowerCase();
- if (keyVal.getKey().startsWith(ACCOUNT_METADATA_PREFIX)) {
- putAccountMetadata(headers, keyInLowercase, keyVal.getValue());
- } else {
- putAccountMetadata(headers, String.format("%s%s", ACCOUNT_METADATA_PREFIX, keyInLowercase),
- keyVal.getValue());
- }
- }
- return (R) request.toBuilder().replaceHeaders(headers.build()).build();
- }
-
- protected void putAccountMetadata(Builder<String, String> headers, String key, String value) {
- headers.put(key, value);
- }
-
- /**
- * @see <a
- * href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/delete-account-metadata.html">documentation</a>
- */
- public static class InRemoval extends BindAccountMetadataToHeaders {
- @Override
- protected void putAccountMetadata(Builder<String, String> headers, String key, String value) {
- headers.put(String.format("x-remove%s", key.substring(1)), "ignored");
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f867518d/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
new file mode 100644
index 0000000..dd3f803
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/BindMetadataToHeaders.java
@@ -0,0 +1,124 @@
+/*
+ * 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.binders;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.rest.Binder;
+
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableMultimap.Builder;
+
+/**
+ * Will lower-case header keys due to a swift implementation to return headers
+ * in a different case than sent. ex.
+ *
+ * <pre>
+ * >> X-Account-Meta-MyDelete1: foo
+ * >> X-Account-Meta-MyDelete2: bar
+ * </pre>
+ *
+ * results in:
+ *
+ * <pre>
+ * << X-Account-Meta-Mydelete1: foo
+ * << X-Account-Meta-Mydelete2: bar
+ * </pre>
+ *
+ * <h4>Note</h4> <br/>
+ * 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 abstract class BindMetadataToHeaders implements Binder {
+
+ public static class BindAccountMetadataToHeaders extends BindMetadataToHeaders {
+ BindAccountMetadataToHeaders() {
+ super("x-account-meta-");
+ }
+ }
+
+ public static class BindRemoveAccountMetadataToHeaders extends BindMetadataToHeaders.ForRemoval {
+ BindRemoveAccountMetadataToHeaders() {
+ super("x-account-meta-");
+ }
+ }
+
+ public static class BindContainerMetadataToHeaders extends BindMetadataToHeaders {
+ BindContainerMetadataToHeaders() {
+ super("x-container-meta-");
+ }
+ }
+
+ public static class BindRemoveContainerMetadataToHeaders extends BindMetadataToHeaders.ForRemoval {
+ BindRemoveContainerMetadataToHeaders() {
+ super("x-container-meta-");
+ }
+ }
+
+ /**
+ * @see <a
+ * href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/delete-account-metadata.html">documentation</a>
+ */
+ public static abstract class ForRemoval extends BindMetadataToHeaders {
+ ForRemoval(String metadataPrefix) {
+ super(metadataPrefix);
+ }
+
+ @Override
+ protected void putMetadata(Builder<String, String> headers, String key, String value) {
+ headers.put(String.format("x-remove%s", key.substring(1)), "ignored");
+ }
+ }
+
+ private final String metadataPrefix;
+
+ BindMetadataToHeaders(String metadataPrefix) {
+ this.metadataPrefix = metadataPrefix;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+ checkNotNull(request, "request");
+ checkArgument(input instanceof Map<?, ?>, "input must be a non-null java.util.Map!");
+ Map<String, String> metadata = Map.class.cast(input);
+ Builder<String, String> headers = ImmutableMultimap.<String, String> builder();
+ for (Entry<String, String> keyVal : metadata.entrySet()) {
+ String keyInLowercase = keyVal.getKey().toLowerCase();
+ if (keyVal.getKey().startsWith(metadataPrefix)) {
+ putMetadata(headers, keyInLowercase, keyVal.getValue());
+ } else {
+ putMetadata(headers, String.format("%s%s", metadataPrefix, keyInLowercase), keyVal.getValue());
+ }
+ }
+ return (R) request.toBuilder().replaceHeaders(headers.build()).build();
+ }
+
+ protected void putMetadata(Builder<String, String> headers, String key, String value) {
+ headers.put(key, value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f867518d/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 fe49b4e..0b0c65c 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
@@ -16,6 +16,8 @@
*/
package org.jclouds.openstack.swift.v1.features;
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+
import java.util.Map;
import javax.inject.Named;
@@ -23,11 +25,11 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.HEAD;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
-import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.swift.v1.binders.BindAccountMetadataToHeaders;
+import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindAccountMetadataToHeaders;
+import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveAccountMetadataToHeaders;
import org.jclouds.openstack.swift.v1.domain.Account;
import org.jclouds.openstack.swift.v1.functions.ParseAccountFromHeaders;
import org.jclouds.rest.annotations.BinderParam;
@@ -49,6 +51,7 @@ import org.jclouds.rest.annotations.ResponseParser;
* Storage Account Services API</a>
*/
@RequestFilters(AuthenticateRequest.class)
+@Consumes(APPLICATION_JSON)
public interface AccountApi {
/**
@@ -60,8 +63,7 @@ public interface AccountApi {
* href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/retrieve-account-metadata.html">
* Get Account Metadata API</a>
*/
- @Named("account:get")
- @Consumes(MediaType.APPLICATION_JSON)
+ @Named("GetAccount")
@HEAD
@ResponseParser(ParseAccountFromHeaders.class)
@Path("/")
@@ -80,12 +82,11 @@ public interface AccountApi {
* @return <code>true</code> if the Account Metadata was successfully created
* or updated, false if not.
*/
- @Named("account:createOrUpdateMetadata")
- @Consumes
+ @Named("UpdateAccountMetadata")
@POST
@Fallback(FalseOnNotFoundOr404.class)
@Path("/")
- boolean createOrUpdateMetadata(@BinderParam(BindAccountMetadataToHeaders.class) Map<String, String> metadata);
+ boolean updateMetadata(@BinderParam(BindAccountMetadataToHeaders.class) Map<String, String> metadata);
/**
* Deletes Account metadata.
@@ -100,10 +101,9 @@ public interface AccountApi {
* href="http://docs.openstack.org/api/openstack-object-storage/1.0/content/delete-account-metadata.html">
* Delete Account Metadata API</a>
*/
- @Named("account:deleteMetadata")
- @Consumes
+ @Named("DeleteAccountMetadata")
@POST
@Fallback(FalseOnNotFoundOr404.class)
@Path("/")
- boolean deleteMetadata(@BinderParam(BindAccountMetadataToHeaders.InRemoval.class) Map<String, String> metadata);
+ boolean deleteMetadata(@BinderParam(BindRemoveAccountMetadataToHeaders.class) Map<String, String> metadata);
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f867518d/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 af9f879..a1b388e 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
@@ -45,13 +45,13 @@ public class AccountApiLiveTest extends BaseSwiftApiLiveTest {
}
}
- public void createOrUpdateMetadata() throws Exception {
+ public void updateMetadata() throws Exception {
for (String regionId : api.configuredRegions()) {
AccountApi accountApi = api.accountApiInRegion(regionId);
Map<String, String> meta = ImmutableMap.of("MyAdd1", "foo", "MyAdd2", "bar");
- assertTrue(accountApi.createOrUpdateMetadata(meta));
+ assertTrue(accountApi.updateMetadata(meta));
accountHasMetadata(accountApi, meta);
}
@@ -63,7 +63,7 @@ public class AccountApiLiveTest extends BaseSwiftApiLiveTest {
Map<String, String> meta = ImmutableMap.of("MyDelete1", "foo", "MyDelete2", "bar");
- assertTrue(accountApi.createOrUpdateMetadata(meta));
+ assertTrue(accountApi.updateMetadata(meta));
accountHasMetadata(accountApi, meta);
assertTrue(accountApi.deleteMetadata(meta));
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/f867518d/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 b561ca2..c2a37c3 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
@@ -23,6 +23,7 @@ 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.BaseSwiftMockTest;
import org.testng.annotations.Test;
@@ -48,9 +49,12 @@ public class AccountApiMockTest extends BaseSwiftMockTest {
try {
SwiftApi api = swiftApi(server.getUrl("/").toString());
- Map<String, String> metadata = api.accountApiInRegion("DFW").get().metadata();
+ Account account = api.accountApiInRegion("DFW").get();
+ assertEquals(account.containerCount(), 3l);
+ assertEquals(account.objectCount(), 42l);
+ assertEquals(account.bytesUsed(), 323479l);
for (Entry<String, String> entry : metadata.entrySet()) {
- assertEquals(metadata.get(entry.getKey().toLowerCase()), entry.getValue());
+ assertEquals(account.metadata().get(entry.getKey().toLowerCase()), entry.getValue());
}
assertEquals(server.getRequestCount(), 2);
@@ -62,7 +66,7 @@ public class AccountApiMockTest extends BaseSwiftMockTest {
}
}
- public void createOrUpdateMetadata() throws Exception {
+ public void updateMetadata() throws Exception {
MockWebServer server = mockSwiftServer();
server.enqueue(new MockResponse().setBody(access));
server.enqueue(accountResponse() //
@@ -71,7 +75,7 @@ public class AccountApiMockTest extends BaseSwiftMockTest {
try {
SwiftApi api = swiftApi(server.getUrl("/").toString());
- assertTrue(api.accountApiInRegion("DFW").createOrUpdateMetadata(metadata));
+ assertTrue(api.accountApiInRegion("DFW").updateMetadata(metadata));
assertEquals(server.getRequestCount(), 2);
assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
[3/3] git commit: JCLOUDS-306. removed dead code
Posted by ad...@apache.org.
JCLOUDS-306. removed dead code
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/commit/49029195
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/49029195
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/49029195
Branch: refs/heads/master
Commit: 49029195765b9fe9408903e89ce17d524ea35550
Parents: f46c86a
Author: Adrian Cole <ad...@gmail.com>
Authored: Fri Sep 27 21:03:07 2013 -0700
Committer: Adrian Cole <ad...@gmail.com>
Committed: Sat Sep 28 07:12:01 2013 -0700
----------------------------------------------------------------------
.../jclouds/openstack/swift/v1/SwiftApi.java | 4 ---
.../swift/v1/config/SwiftHttpApiModule.java | 34 --------------------
2 files changed, 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/49029195/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 562566b..547c356 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
@@ -25,7 +25,6 @@ import org.jclouds.location.functions.RegionToEndpoint;
import org.jclouds.openstack.swift.v1.features.AccountApi;
import org.jclouds.openstack.swift.v1.features.ContainerApi;
import org.jclouds.openstack.swift.v1.features.ObjectApi;
-import org.jclouds.openstack.v2_0.features.ExtensionApi;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
@@ -45,9 +44,6 @@ public interface SwiftApi extends Closeable {
Set<String> configuredRegions();
@Delegate
- ExtensionApi extensionApiInRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
-
- @Delegate
AccountApi accountApiInRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
@Delegate
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/49029195/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 1822ebb..c0c68c7 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,11 +15,6 @@
* limitations under the License.
*/
package org.jclouds.openstack.swift.v1.config;
-import java.net.URI;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-import javax.inject.Provider;
-import javax.inject.Singleton;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
@@ -28,17 +23,8 @@ import org.jclouds.json.config.GsonModule.DateAdapter;
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
import org.jclouds.openstack.swift.v1.SwiftApi;
import org.jclouds.openstack.swift.v1.handlers.SwiftErrorHandler;
-import org.jclouds.openstack.v2_0.domain.Extension;
-import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.config.HttpApiModule;
-import org.jclouds.rest.functions.ImplicitOptionalConverter;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.Multimap;
-import com.google.inject.Provides;
/**
* @author Adrian Cole
@@ -53,28 +39,8 @@ public class SwiftHttpApiModule extends HttpApiModule<SwiftApi> {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
- bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
super.configure();
}
-
- @Provides
- @Singleton
- public Multimap<URI, URI> aliases() {
- return ImmutableMultimap.<URI, URI>builder()
- .build();
- }
-
- @Provides
- @Singleton
- public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final Provider<SwiftApi> swiftApi) {
- return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
- .build(new CacheLoader<String, Set<? extends Extension>>() {
- @Override
- public Set<? extends Extension> load(String key) throws Exception {
- return swiftApi.get().extensionApiInRegion(key).list();
- }
- });
- }
@Override
protected void bindErrorHandlers() {