Updated Branches: refs/heads/master 2150c8b65 -> 83a1c202e
JCLOUDS-306. added public acl to openstack-swift 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/83a1c202 Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/83a1c202 Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/83a1c202 Branch: refs/heads/master Commit: 83a1c202ed42612875c00c1b9bf5a8f8df3a3582 Parents: 2150c8b Author: Adrian Cole <[email protected]> Authored: Sat Sep 28 15:35:56 2013 -0700 Committer: Adrian Cole <[email protected]> Committed: Sat Sep 28 15:58:37 2013 -0700 ---------------------------------------------------------------------- .../openstack/swift/v1/domain/SwiftObject.java | 47 ++++++---- .../swift/v1/features/ContainerApi.java | 22 ++++- .../openstack/swift/v1/features/ObjectApi.java | 3 + .../v1/functions/ParseObjectFromResponse.java | 5 + .../functions/ParseObjectListFromResponse.java | 99 ++++++++++++++++++++ .../swift/v1/features/ContainerApiLiveTest.java | 3 +- .../swift/v1/features/ContainerApiMockTest.java | 33 +++++-- .../features/CreatePublicContainerLiveTest.java | 65 +++++++++++++ .../swift/v1/features/ObjectApiLiveTest.java | 18 +++- .../swift/v1/features/ObjectApiMockTest.java | 32 ++++--- 10 files changed, 285 insertions(+), 42 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/83a1c202/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 6904436..56ceba4 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 @@ -20,13 +20,13 @@ 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 java.beans.ConstructorProperties; +import java.net.URI; import java.util.Date; import java.util.Map; import java.util.Map.Entry; +import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.io.Payload; -import org.jclouds.io.Payloads; import org.jclouds.openstack.swift.v1.features.ObjectApi; import com.google.common.base.Objects; @@ -41,18 +41,16 @@ import com.google.common.collect.ImmutableMap; public class SwiftObject implements Comparable<SwiftObject> { private final String name; + private final URI uri; private final String hash; private final Date lastModified; private final Map<String, String> metadata; private final Payload payload; - @ConstructorProperties({ "name", "hash", "bytes", "content_type", "last_modified" }) - protected SwiftObject(String name, String hash, long bytes, String contentType, Date lastModified) { - this(name, hash, lastModified, ImmutableMap.<String, String> of(), payload(bytes, contentType)); - } - - protected SwiftObject(String name, String hash, Date lastModified, Map<String, String> metadata, Payload payload) { + protected SwiftObject(String name, URI uri, String hash, Date lastModified, Map<String, String> metadata, + Payload payload) { this.name = checkNotNull(name, "name"); + this.uri = checkNotNull(uri, "uri of %s", uri); this.hash = checkNotNull(hash, "hash of %s", name); this.lastModified = checkNotNull(lastModified, "lastModified of %s", name); this.metadata = metadata == null ? ImmutableMap.<String, String> of() : metadata; @@ -63,6 +61,14 @@ public class SwiftObject implements Comparable<SwiftObject> { return name; } + /** + * http location of the object, accessible if its container is + * {@link CreateContainerOptions#publicRead}. + */ + public URI uri() { + return uri; + } + public String hash() { return hash; } @@ -100,6 +106,7 @@ 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(hash(), that.hash()); } else { return false; @@ -108,7 +115,7 @@ public class SwiftObject implements Comparable<SwiftObject> { @Override public int hashCode() { - return Objects.hashCode(name(), hash()); + return Objects.hashCode(name(), uri(), hash()); } @Override @@ -119,6 +126,7 @@ public class SwiftObject implements Comparable<SwiftObject> { protected ToStringHelper string() { return toStringHelper("") // .add("name", name()) // + .add("uri", uri()) // .add("hash", hash()) // .add("lastModified", lastModified()) // .add("metadata", metadata()); @@ -143,6 +151,7 @@ public class SwiftObject implements Comparable<SwiftObject> { public static class Builder { protected String name; + protected URI uri; protected String hash; protected Date lastModified; protected Payload payload; @@ -157,6 +166,14 @@ public class SwiftObject implements Comparable<SwiftObject> { } /** + * @see SwiftObject#uri() + */ + public Builder uri(URI uri) { + this.uri = checkNotNull(uri, "uri"); + return this; + } + + /** * @see SwiftObject#hash() */ public Builder hash(String hash) { @@ -196,24 +213,16 @@ public class SwiftObject implements Comparable<SwiftObject> { } public SwiftObject build() { - return new SwiftObject(name, hash, lastModified, metadata, payload); + return new SwiftObject(name, uri, hash, lastModified, metadata, payload); } public Builder fromObject(SwiftObject from) { return name(from.name()) // + .uri(from.uri()) // .hash(from.hash()) // .lastModified(from.lastModified()) // .metadata(from.metadata()) // .payload(from.payload()); } } - - 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/incubator-jclouds-labs-openstack/blob/83a1c202/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 a1b7ae7..e108ab3 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,6 +34,8 @@ 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; @@ -41,6 +43,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.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Fallback; import org.jclouds.rest.annotations.QueryParams; @@ -94,6 +97,10 @@ public interface ContainerApi { * * @param containerName * corresponds to {@link Container#name()}. + * @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> @@ -104,7 +111,20 @@ public interface ContainerApi { @PUT @ResponseParser(FalseOnAccepted.class) @Path("/{containerName}") - boolean createIfAbsent(@PathParam("containerName") String 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; + } + } /** * Gets the {@link Container}. http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/83a1c202/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 2a3ee1e..05995af 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 @@ -45,6 +45,7 @@ import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveOb import org.jclouds.openstack.swift.v1.domain.SwiftObject; import org.jclouds.openstack.swift.v1.functions.ETagHeader; import org.jclouds.openstack.swift.v1.functions.ParseObjectFromResponse; +import org.jclouds.openstack.swift.v1.functions.ParseObjectListFromResponse; import org.jclouds.rest.Binder; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Fallback; @@ -71,6 +72,7 @@ public interface ObjectApi { @Named("ListObjects") @GET @QueryParams(keys = "format", values = "json") + @ResponseParser(ParseObjectListFromResponse.class) @Fallback(EmptyFluentIterableOnNotFoundOr404.class) @Path("/") FluentIterable<SwiftObject> listFirstPage(); @@ -86,6 +88,7 @@ public interface ObjectApi { @Named("ListObjects") @GET @QueryParams(keys = "format", values = "json") + @ResponseParser(ParseObjectListFromResponse.class) @Fallback(EmptyFluentIterableOnNotFoundOr404.class) @Path("/") FluentIterable<SwiftObject> listAt(@QueryParam("marker") String marker); http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/83a1c202/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 c5533a4..36247e1 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 @@ -19,6 +19,8 @@ package org.jclouds.openstack.swift.v1.functions; import static com.google.common.net.HttpHeaders.ETAG; import static com.google.common.net.HttpHeaders.LAST_MODIFIED; +import java.net.URI; + import javax.inject.Inject; import org.jclouds.date.DateService; @@ -39,11 +41,13 @@ public class ParseObjectFromResponse implements Function<HttpResponse, SwiftObje this.dates = dates; } + private String uri; private String name; @Override public SwiftObject apply(HttpResponse from) { return SwiftObject.builder() // + .uri(URI.create(uri)) // .name(name) // .hash(from.getFirstHeaderOrNull(ETAG)) // .payload(from.getPayload()) // @@ -53,6 +57,7 @@ public class ParseObjectFromResponse implements Function<HttpResponse, SwiftObje @Override public ParseObjectFromResponse setContext(HttpRequest request) { + this.uri = request.getEndpoint().toString(); 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/83a1c202/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 new file mode 100644 index 0000000..feb00c8 --- /dev/null +++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java @@ -0,0 +1,99 @@ +/* + * 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 java.net.URI; +import java.util.Date; +import java.util.List; + +import javax.inject.Inject; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ParseJson; +import org.jclouds.io.Payload; +import org.jclouds.io.Payloads; +import org.jclouds.openstack.swift.v1.domain.SwiftObject; +import org.jclouds.rest.InvocationContext; + +import com.google.common.base.Function; +import com.google.common.collect.FluentIterable; + +public class ParseObjectListFromResponse implements Function<HttpResponse, FluentIterable<SwiftObject>>, + InvocationContext<ParseObjectListFromResponse> { + + private static final class InternalObject { + String name; + String hash; + long bytes; + String content_type; + Date last_modified; + } + + private final ParseJson<List<InternalObject>> json; + + @Inject + ParseObjectListFromResponse(ParseJson<List<InternalObject>> json) { + this.json = json; + } + + private ToSwiftObject toSwiftObject; + + @Override + public FluentIterable<SwiftObject> apply(HttpResponse from) { + return FluentIterable.from(json.apply(from)) // + .transform(toSwiftObject); + } + + static class ToSwiftObject implements Function<InternalObject, SwiftObject> { + private final String containerUri; + + ToSwiftObject(String containerUri) { + this.containerUri = containerUri; + } + + @Override + public SwiftObject apply(InternalObject input) { + return SwiftObject.builder() // + .uri(URI.create(String.format("%s%s", containerUri, input.name))) // + .name(input.name) // + .hash(input.hash) // + .payload(payload(input.bytes, input.content_type)) // + .lastModified(input.last_modified).build(); + } + } + + @Override + public ParseObjectListFromResponse setContext(HttpRequest request) { + String containerUri = request.getEndpoint().toString(); + int queryIndex = containerUri.indexOf('?'); + if (queryIndex != -1) { + containerUri = containerUri.substring(0, queryIndex); + } + this.toSwiftObject = new ToSwiftObject(containerUri); + return this; + } + + 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/incubator-jclouds-labs-openstack/blob/83a1c202/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 973d363..bf0c24c 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,6 +24,7 @@ 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.testng.annotations.AfterClass; @@ -118,7 +119,7 @@ public class ContainerApiLiveTest extends BaseSwiftApiLiveTest { public void setup() { super.setup(); for (String regionId : api.configuredRegions()) { - api.containerApiInRegion(regionId).createIfAbsent(name); + api.containerApiInRegion(regionId).createIfAbsent(name, new CreateContainerOptions()); } } http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/83a1c202/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 d54530e..b127799 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 @@ -23,6 +23,7 @@ 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; @@ -107,18 +108,38 @@ public class ContainerApiMockTest extends BaseSwiftMockTest { try { SwiftApi api = swiftApi(server.getUrl("/").toString()); - assertTrue(api.containerApiInRegion("DFW").createIfAbsent("myContainer")); + assertTrue(api.containerApiInRegion("DFW").createIfAbsent("myContainer", new CreateContainerOptions())); assertEquals(server.getRequestCount(), 2); assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); - RecordedRequest deleteRequest = server.takeRequest(); - assertEquals(deleteRequest.getRequestLine(), + RecordedRequest createRequest = server.takeRequest(); + assertEquals(createRequest.getRequestLine(), "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1"); } finally { server.shutdown(); } } + public void createPublicRead() 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())); + + 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"); + assertEquals(createRequest.getHeader("x-container-read"), ".r:*,.rlistings"); + } finally { + server.shutdown(); + } + } + public void alreadyCreated() throws Exception { MockWebServer server = mockSwiftServer(); server.enqueue(new MockResponse().setBody(access)); @@ -126,12 +147,12 @@ public class ContainerApiMockTest extends BaseSwiftMockTest { try { SwiftApi api = swiftApi(server.getUrl("/").toString()); - assertFalse(api.containerApiInRegion("DFW").createIfAbsent("myContainer")); + assertFalse(api.containerApiInRegion("DFW").createIfAbsent("myContainer", new CreateContainerOptions())); assertEquals(server.getRequestCount(), 2); assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); - RecordedRequest deleteRequest = server.takeRequest(); - assertEquals(deleteRequest.getRequestLine(), + RecordedRequest createRequest = server.takeRequest(); + assertEquals(createRequest.getRequestLine(), "PUT /v1/MossoCloudFS_5bcf396e-39dd-45ff-93a1-712b9aba90a9/myContainer HTTP/1.1"); } finally { server.shutdown(); http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/83a1c202/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 new file mode 100644 index 0000000..70a84b9 --- /dev/null +++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/CreatePublicContainerLiveTest.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.features; + +import static org.jclouds.blobstore.options.CreateContainerOptions.Builder.publicRead; +import static org.jclouds.io.Payloads.newStringPayload; +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.http.options.GetOptions; +import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest; +import org.jclouds.util.Strings2; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; + +/** + * @author Adrian Cole + */ +@Test(groups = "live", testName = "CreatePublicContainerLiveTest") +public class CreatePublicContainerLiveTest extends BaseSwiftApiLiveTest { + + private String name = getClass().getSimpleName(); + private String containerName = getClass().getSimpleName() + "Container"; + + public void publicReadObjectUri() throws Exception { + for (String regionId : api.configuredRegions()) { + api.containerApiInRegion(regionId).createIfAbsent(containerName, publicRead()); + api.containerApiInRegion(regionId).get(containerName); + + ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName); + objectApi.createOrUpdate(name, newStringPayload("swifty"), ImmutableMap.<String, String> of()); + + InputStream publicStream = objectApi.get(name, new GetOptions()).uri().toURL().openStream(); + + assertEquals(Strings2.toStringAndClose(publicStream), "swifty"); + } + } + + @Override + @AfterClass(groups = "live") + public void tearDown() { + for (String regionId : api.configuredRegions()) { + api.objectApiInRegionForContainer(regionId, containerName).delete(name); + api.containerApiInRegion(regionId).deleteIfEmpty(containerName); + } + super.tearDown(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/83a1c202/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 4960fed..4cfa8d3 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 @@ -23,11 +23,14 @@ 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 static org.testng.Assert.fail; +import java.io.IOException; 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; @@ -61,6 +64,7 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest { static void checkObject(SwiftObject object) { assertNotNull(object.name()); + assertNotNull(object.uri()); assertNotNull(object.hash()); assertTrue(object.lastModified().getTime() <= System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5)); assertNotNull(object.payload().getContentMetadata().getContentLength()); @@ -85,6 +89,17 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest { } } + public void privateByDefault() throws Exception { + for (String regionId : api.configuredRegions()) { + SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).head(name); + try { + object.uri().toURL().openStream(); + fail("shouldn't be able to access " + object); + } catch (IOException expected) { + } + } + } + public void getOptions() throws Exception { for (String regionId : api.configuredRegions()) { SwiftObject object = api.objectApiInRegionForContainer(regionId, containerName).get(name, tail(1)); @@ -107,7 +122,6 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest { public void updateMetadata() throws Exception { for (String regionId : api.configuredRegions()) { ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName); - ; Map<String, String> meta = ImmutableMap.of("MyAdd1", "foo", "MyAdd2", "bar"); @@ -149,7 +163,7 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest { public void setup() { super.setup(); for (String regionId : api.configuredRegions()) { - api.containerApiInRegion(regionId).createIfAbsent(containerName); + api.containerApiInRegion(regionId).createIfAbsent(containerName, new CreateContainerOptions()); api.objectApiInRegionForContainer(regionId, containerName).createOrUpdate(name, newStringPayload("swifty"), ImmutableMap.<String, String> of()); } http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/83a1c202/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 63c9974..1cef6fe 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 @@ -23,6 +23,7 @@ import static org.jclouds.io.Payloads.newStringPayload; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; +import java.net.URI; import java.util.Map; import java.util.Map.Entry; @@ -59,17 +60,22 @@ public class ObjectApiMockTest extends BaseSwiftMockTest { + " \"last_modified\":\"2009-02-03T05:26:32.612278\"},\n" // + "]"; - ImmutableList<SwiftObject> parsedObjects = ImmutableList.of(// - SwiftObject.builder() // - .name("test_obj_1") // - .hash("4281c348eaf83e70ddce0e07221c3d28") // - .payload(payload(14, "application/octet-stream")) // - .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build(), // - SwiftObject.builder() // - .name("test_obj_2") // - .hash("b039efe731ad111bc1b0ef221c3849d0") // - .payload(payload(64l, "application/octet-stream")) // - .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build()); + 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")) // + .hash("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")) // + .hash("b039efe731ad111bc1b0ef221c3849d0") // + .payload(payload(64l, "application/octet-stream")) // + .lastModified(dates.iso8601DateParse("2009-02-03T05:26:32.612278")).build()); + } public void listFirstPage() throws Exception { MockWebServer server = mockSwiftServer(); @@ -80,7 +86,7 @@ public class ObjectApiMockTest extends BaseSwiftMockTest { SwiftApi api = swiftApi(server.getUrl("/").toString()); ImmutableList<SwiftObject> objects = api.objectApiInRegionForContainer("DFW", "myContainer").listFirstPage() .toList(); - assertEquals(objects, parsedObjects); + assertEquals(objects, parsedObjectsForUrl(server.getUrl("/").toString())); assertEquals(server.getRequestCount(), 2); assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); @@ -100,7 +106,7 @@ public class ObjectApiMockTest extends BaseSwiftMockTest { SwiftApi api = swiftApi(server.getUrl("/").toString()); ImmutableList<SwiftObject> objects = api.objectApiInRegionForContainer("DFW", "myContainer").listAt("test") .toList(); - assertEquals(objects, parsedObjects); + assertEquals(objects, parsedObjectsForUrl(server.getUrl("/").toString())); assertEquals(server.getRequestCount(), 2); assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
