JCLOUDS-306. switch to swift-specific CreateContainerOptions
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/38bcafda Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/38bcafda Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/38bcafda Branch: refs/heads/master Commit: 38bcafda5a1e3404e05c85a014fa0feab9e1cbd5 Parents: 83a1c20 Author: Adrian Cole <[email protected]> Authored: Sat Sep 28 16:31:27 2013 -0700 Committer: Adrian Cole <[email protected]> Committed: Sat Sep 28 17:13:22 2013 -0700 ---------------------------------------------------------------------- .../swift/v1/binders/BindMetadataToHeaders.java | 28 +++++---- .../swift/v1/features/ContainerApi.java | 19 +----- .../v1/options/CreateContainerOptions.java | 65 ++++++++++++++++++++ .../swift/v1/features/ContainerApiLiveTest.java | 2 +- .../swift/v1/features/ContainerApiMockTest.java | 10 ++- .../features/CreatePublicContainerLiveTest.java | 6 +- .../swift/v1/features/ObjectApiLiveTest.java | 2 +- 7 files changed, 95 insertions(+), 37 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/38bcafda/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 262938e..1a69a0f 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 @@ -52,7 +52,7 @@ import com.google.common.collect.ImmutableMultimap.Builder; * @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 class BindMetadataToHeaders implements Binder { public static class BindAccountMetadataToHeaders extends BindMetadataToHeaders { BindAccountMetadataToHeaders() { @@ -107,8 +107,8 @@ public abstract class BindMetadataToHeaders implements Binder { private final String metadataPrefix; - BindMetadataToHeaders(String metadataPrefix) { - this.metadataPrefix = metadataPrefix; + public BindMetadataToHeaders(String metadataPrefix) { + this.metadataPrefix = checkNotNull(metadataPrefix, "metadataPrefix"); } @SuppressWarnings("unchecked") @@ -117,20 +117,24 @@ public abstract class BindMetadataToHeaders implements Binder { 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(); + ImmutableMultimap<String, String> headers = toHeaders(metadata); + return (R) request.toBuilder().replaceHeaders(headers).build(); + } + + protected void putMetadata(Builder<String, String> headers, String key, String value) { + headers.put(key, value); + } + + public ImmutableMultimap<String, String> toHeaders(Map<String, String> metadata) { + Builder<String, String> builder = 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()); + putMetadata(builder, keyInLowercase, keyVal.getValue()); } else { - putMetadata(headers, String.format("%s%s", metadataPrefix, keyInLowercase), keyVal.getValue()); + putMetadata(builder, String.format("%s%s", metadataPrefix, keyInLowercase), keyVal.getValue()); } } - return (R) request.toBuilder().replaceHeaders(headers.build()).build(); + return builder.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/38bcafda/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 e108ab3..d9438fa 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 @@ -34,8 +34,6 @@ import javax.ws.rs.QueryParam; import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404; import org.jclouds.Fallbacks.FalseOnNotFoundOr404; import org.jclouds.Fallbacks.NullOnNotFoundOr404; -import org.jclouds.blobstore.options.CreateContainerOptions; -import org.jclouds.http.HttpRequest; import org.jclouds.javax.annotation.Nullable; import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest; import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindContainerMetadataToHeaders; @@ -43,7 +41,7 @@ import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveCo 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.rest.Binder; +import org.jclouds.openstack.swift.v1.options.CreateContainerOptions; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Fallback; import org.jclouds.rest.annotations.QueryParams; @@ -111,20 +109,7 @@ public interface ContainerApi { @PUT @ResponseParser(FalseOnAccepted.class) @Path("/{containerName}") - boolean createIfAbsent(@PathParam("containerName") String containerName, - @BinderParam(ContainerReadHeader.class) CreateContainerOptions options); - - static class ContainerReadHeader implements Binder { - @SuppressWarnings("unchecked") - @Override - public <R extends HttpRequest> R bindToRequest(R request, Object input) { - CreateContainerOptions options = CreateContainerOptions.class.cast(input); - if (options.isPublicRead()) { - return (R) request.toBuilder().addHeader("x-container-read", ".r:*,.rlistings").build(); - } - return request; - } - } + boolean createIfAbsent(@PathParam("containerName") String containerName, CreateContainerOptions options); /** * Gets the {@link Container}. http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/38bcafda/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 new file mode 100644 index 0000000..09a3c77 --- /dev/null +++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/options/CreateContainerOptions.java @@ -0,0 +1,65 @@ +/* + * 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 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>. + * + * @see ContainerApi#createIfAbsent + */ +public class CreateContainerOptions extends BaseHttpRequestOptions { + + /** corresponds to {@link Container#metadata()} */ + public CreateContainerOptions metadata(Map<String, String> metadata) { + if (!metadata.isEmpty()) { + this.headers.putAll(bindMetadataToHeaders.toHeaders(metadata)); + } + return this; + } + + /** Sets the ACL the container so that anybody can read it. */ + public CreateContainerOptions anybodyRead() { + this.headers.put("x-container-read", ".r:*,.rlistings"); + return this; + } + + public static class Builder { + + /** @see CreateContainerOptions#anybodyRead */ + public static CreateContainerOptions anybodyRead() { + CreateContainerOptions options = new CreateContainerOptions(); + return options.anybodyRead(); + } + + /** @see CreateContainerOptions#metadata */ + public static CreateContainerOptions metadata(Map<String, String> metadata) { + CreateContainerOptions options = new CreateContainerOptions(); + return options.metadata(metadata); + } + } + + private static final BindMetadataToHeaders bindMetadataToHeaders = new BindMetadataToHeaders("x-container-meta-"); +} http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/38bcafda/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 bf0c24c..7a21b2c 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,9 @@ import static org.testng.Assert.assertTrue; import java.util.Map; import java.util.Map.Entry; -import org.jclouds.blobstore.options.CreateContainerOptions; 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.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/38bcafda/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 b127799..159021e 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 @@ -16,6 +16,7 @@ */ package org.jclouds.openstack.swift.v1.features; +import static org.jclouds.openstack.swift.v1.options.CreateContainerOptions.Builder.anybodyRead; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; @@ -23,10 +24,10 @@ import static org.testng.Assert.assertTrue; import java.util.Map; import java.util.Map.Entry; -import org.jclouds.blobstore.options.CreateContainerOptions; 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.jclouds.openstack.swift.v1.options.CreateContainerOptions; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; @@ -120,14 +121,14 @@ public class ContainerApiMockTest extends BaseSwiftMockTest { } } - public void createPublicRead() throws Exception { + public void createWithOptions() 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", new CreateContainerOptions().publicRead())); + assertTrue(api.containerApiInRegion("DFW").createIfAbsent("myContainer", anybodyRead().metadata(metadata))); assertEquals(server.getRequestCount(), 2); assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); @@ -135,6 +136,9 @@ public class ContainerApiMockTest extends BaseSwiftMockTest { assertEquals(createRequest.getRequestLine(), "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1"); assertEquals(createRequest.getHeader("x-container-read"), ".r:*,.rlistings"); + for (Entry<String, String> entry : metadata.entrySet()) { + assertEquals(createRequest.getHeader("x-container-meta-" + entry.getKey().toLowerCase()), entry.getValue()); + } } finally { server.shutdown(); } http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/38bcafda/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 70a84b9..3eca7ed 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 @@ -16,8 +16,8 @@ */ package org.jclouds.openstack.swift.v1.features; -import static org.jclouds.blobstore.options.CreateContainerOptions.Builder.publicRead; import static org.jclouds.io.Payloads.newStringPayload; +import static org.jclouds.openstack.swift.v1.options.CreateContainerOptions.Builder.anybodyRead; import static org.testng.Assert.assertEquals; import java.io.InputStream; @@ -39,9 +39,9 @@ public class CreatePublicContainerLiveTest extends BaseSwiftApiLiveTest { private String name = getClass().getSimpleName(); private String containerName = getClass().getSimpleName() + "Container"; - public void publicReadObjectUri() throws Exception { + public void anybodyReadObjectUri() throws Exception { for (String regionId : api.configuredRegions()) { - api.containerApiInRegion(regionId).createIfAbsent(containerName, publicRead()); + api.containerApiInRegion(regionId).createIfAbsent(containerName, anybodyRead()); api.containerApiInRegion(regionId).get(containerName); ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName); http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/38bcafda/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 4cfa8d3..5d9ac6c 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 @@ -30,10 +30,10 @@ import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; -import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.http.options.GetOptions; import org.jclouds.openstack.swift.v1.domain.SwiftObject; import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest; +import org.jclouds.openstack.swift.v1.options.CreateContainerOptions; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test;
