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/30 09:16:40 UTC
[1/3] git commit: JCLOUDS-300. Add BlobStore abstraction to
openstack-swift api
Updated Branches:
refs/heads/master fd3f8cd01 -> cbac63e18
JCLOUDS-300. Add BlobStore abstraction to openstack-swift api
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/cbac63e1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/cbac63e1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/cbac63e1
Branch: refs/heads/master
Commit: cbac63e184d6e24ba3503cb7d95edb6e2df6f9d4
Parents: 0426ebf
Author: Adrian Cole <ad...@gmail.com>
Authored: Sun Sep 29 23:53:04 2013 -0700
Committer: Adrian Cole <ad...@gmail.com>
Committed: Mon Sep 30 00:16:17 2013 -0700
----------------------------------------------------------------------
openstack-swift/pom.xml | 13 +-
.../openstack/swift/v1/SwiftApiMetadata.java | 9 +-
.../openstack/swift/v1/TemporaryUrlSigner.java | 11 +-
.../blobstore/RegionScopedSwiftBlobStore.java | 208 ++++++++++++++
.../RegionScopedTemporaryUrlBlobSigner.java | 102 +++++++
.../config/SignUsingTemporaryUrls.java | 78 +++++
.../config/SwiftBlobStoreContextModule.java | 34 +++
.../v1/blobstore/functions/ToBlobMetadata.java | 71 +++++
.../functions/ToListContainerOptions.java | 52 ++++
.../blobstore/functions/ToResourceMetadata.java | 45 +++
.../v1/blobstore/functions/ToSwiftObject.java | 55 ++++
.../internal/SubmissionAsyncBlobStore.java | 284 +++++++++++++++++++
.../SwiftBlobIntegrationLiveTest.java | 75 +++++
.../integration/SwiftBlobLiveTest.java | 38 +++
.../integration/SwiftBlobSignerLiveTest.java | 38 +++
.../SwiftContainerIntegrationLiveTest.java | 53 ++++
.../integration/SwiftContainerLiveTest.java | 38 +++
.../SwiftServiceIntegrationLiveTest.java | 38 +++
openstack-swift/src/test/resources/logback.xml | 2 +
19 files changed, 1228 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/pom.xml
----------------------------------------------------------------------
diff --git a/openstack-swift/pom.xml b/openstack-swift/pom.xml
index 9520153..2debd5e 100644
--- a/openstack-swift/pom.xml
+++ b/openstack-swift/pom.xml
@@ -41,17 +41,10 @@
<test.openstack-swift.identity>FIXME_IDENTITY</test.openstack-swift.identity>
<test.openstack-swift.credential>FIXME_CREDENTIALS</test.openstack-swift.credential>
<test.jclouds.keystone.credential-type>passwordCredentials</test.jclouds.keystone.credential-type>
- <jclouds.blobstore.httpstream.url>FIXME_HTTPURL</jclouds.blobstore.httpstream.url>
- <jclouds.blobstore.httpstream.md5>FIXME_HTTPMD5</jclouds.blobstore.httpstream.md5>
-
+ <jclouds.blobstore.httpstream.url>http://archive.apache.org/dist/commons/logging/binaries/commons-logging-1.1.1-bin.tar.gz</jclouds.blobstore.httpstream.url>
+ <jclouds.blobstore.httpstream.md5>e5de09672af9b386c30a311654d8541a</jclouds.blobstore.httpstream.md5>
<jclouds.osgi.export>org.jclouds.openstack.swift.v1*;version="${project.version}"</jclouds.osgi.export>
- <jclouds.osgi.import>
- org.jclouds.blobstore.internal;version="${jclouds.version}",
- org.jclouds.rest.internal;version="${jclouds.version}",
- org.jclouds.labs*;version="${project.version}",
- org.jclouds*;version="${jclouds.version}",
- *
- </jclouds.osgi.import>
+ <jclouds.osgi.import>org.jclouds*;version="${project.version}",*</jclouds.osgi.import>
</properties>
<repositories>
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
index 1c08c78..a3ce97c 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
@@ -18,15 +18,19 @@ package org.jclouds.openstack.swift.v1;
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.reflect.Reflection2.typeToken;
import java.net.URI;
import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
+import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.openstack.keystone.v2_0.config.AuthenticationApiModule;
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.swift.v1.blobstore.config.SignUsingTemporaryUrls;
+import org.jclouds.openstack.swift.v1.blobstore.config.SwiftBlobStoreContextModule;
import org.jclouds.openstack.swift.v1.config.SwiftHttpApiModule;
import org.jclouds.openstack.swift.v1.config.SwiftTypeAdapters;
import org.jclouds.openstack.v2_0.ServiceType;
@@ -75,12 +79,15 @@ public class SwiftApiMetadata extends BaseHttpApiMetadata<SwiftApi> {
.endpointName("KeyStone base url ending in /v2.0/")
.defaultEndpoint("http://localhost:5000/v2.0/")
.defaultProperties(SwiftApiMetadata.defaultProperties())
+ .view(typeToken(BlobStoreContext.class))
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(AuthenticationApiModule.class)
.add(KeystoneAuthenticationModule.class)
.add(RegionModule.class)
.add(SwiftTypeAdapters.class)
- .add(SwiftHttpApiModule.class).build());
+ .add(SwiftHttpApiModule.class)
+ .add(SwiftBlobStoreContextModule.class)
+ .add(SignUsingTemporaryUrls.class).build());
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java
index 35f2b12..7a3cf8b 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/TemporaryUrlSigner.java
@@ -1,9 +1,10 @@
/*
- * Copyright 2013 Netflix, Inc.
- *
- * Licensed 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
+ * 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
*
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
new file mode 100644
index 0000000..ad88550
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStore.java
@@ -0,0 +1,208 @@
+/*
+ * 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.blobstore;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.jclouds.blobstore.BlobStoreContext;
+import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.domain.BlobMetadata;
+import org.jclouds.blobstore.domain.MutableBlobMetadata;
+import org.jclouds.blobstore.domain.PageSet;
+import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.blobstore.domain.internal.BlobImpl;
+import org.jclouds.blobstore.domain.internal.PageSetImpl;
+import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
+import org.jclouds.blobstore.internal.BaseBlobStore;
+import org.jclouds.blobstore.options.CreateContainerOptions;
+import org.jclouds.blobstore.options.GetOptions;
+import org.jclouds.blobstore.options.ListContainerOptions;
+import org.jclouds.blobstore.options.PutOptions;
+import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
+import org.jclouds.blobstore.util.BlobUtils;
+import org.jclouds.domain.Location;
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.blobstore.functions.ToBlobMetadata;
+import org.jclouds.openstack.swift.v1.blobstore.functions.ToListContainerOptions;
+import org.jclouds.openstack.swift.v1.blobstore.functions.ToResourceMetadata;
+import org.jclouds.openstack.swift.v1.domain.Container;
+import org.jclouds.openstack.swift.v1.domain.ObjectList;
+import org.jclouds.openstack.swift.v1.domain.SwiftObject;
+import org.jclouds.openstack.swift.v1.features.ObjectApi;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+
+public class RegionScopedSwiftBlobStore extends BaseBlobStore {
+
+ private final BlobToHttpGetOptions toGetOptions = new BlobToHttpGetOptions();
+ private final ToListContainerOptions toListContainerOptions = new ToListContainerOptions();
+
+ private final SwiftApi api;
+ private final Supplier<Location> region;
+ private final ToResourceMetadata toResourceMetadata;
+ private final FetchBlobMetadata fetchMetadata;
+
+ @Inject
+ protected RegionScopedSwiftBlobStore(BlobStoreContext context, BlobUtils blobUtils, final Supplier<Location> region,
+ SwiftApi api, FetchBlobMetadata fetchMetadata) {
+ super(context, blobUtils, region, new Supplier<Set<? extends Location>>() {
+ @Override
+ public Set<? extends Location> get() {
+ return ImmutableSet.of(region.get());
+ }
+ });
+ this.api = api;
+ this.toResourceMetadata = new ToResourceMetadata(region);
+ this.region = region;
+ this.fetchMetadata = fetchMetadata;
+ }
+
+ /** all commands are scoped to a region. */
+ protected String regionId() {
+ return region.get().getId();
+ }
+
+ @Override
+ public PageSet<? extends StorageMetadata> list() {
+ // TODO: there may eventually be >10k containers..
+ FluentIterable<StorageMetadata> containers = api.containerApiInRegion(regionId()).listFirstPage()
+ .transform(toResourceMetadata);
+ return new PageSetImpl<StorageMetadata>(containers, null);
+ }
+
+ @Override
+ public boolean containerExists(String container) {
+ Container val = api.containerApiInRegion(regionId()).get(container);
+ containerCache.put(container, Optional.fromNullable(val));
+ return val != null;
+ }
+
+ @Override
+ public boolean createContainerInLocation(Location location, String container) {
+ return createContainerInLocation(location, container, CreateContainerOptions.NONE);
+ }
+
+ @Override
+ public boolean createContainerInLocation(Location location, String container, CreateContainerOptions options) {
+ checkArgument(location == null || location.equals(region.get()), "location must be null or %s", region.get());
+ if (options.isPublicRead()) {
+ return api.containerApiInRegion(regionId()).createIfAbsent(container, ANYBODY_READ);
+ }
+ return api.containerApiInRegion(regionId()).createIfAbsent(container, BASIC_CONTAINER);
+ }
+
+ private static final org.jclouds.openstack.swift.v1.options.CreateContainerOptions BASIC_CONTAINER = new org.jclouds.openstack.swift.v1.options.CreateContainerOptions();
+ private static final org.jclouds.openstack.swift.v1.options.CreateContainerOptions ANYBODY_READ = new org.jclouds.openstack.swift.v1.options.CreateContainerOptions()
+ .anybodyRead();
+
+ @Override
+ public PageSet<? extends StorageMetadata> list(String container, ListContainerOptions options) {
+ ObjectApi objectApi = api.objectApiInRegionForContainer(regionId(), container);
+ ObjectList objects = objectApi.list(toListContainerOptions.apply(options));
+ if (objects == null) {
+ containerCache.put(container, Optional.<Container> absent());
+ return new PageSetImpl<StorageMetadata>(ImmutableList.<StorageMetadata> of(), null);
+ } else {
+ containerCache.put(container, Optional.of(objects.container()));
+ List<MutableBlobMetadata> list = Lists.transform(objects, toBlobMetadata(container));
+ int limit = Optional.fromNullable(options.getMaxResults()).or(10000);
+ String marker = list.size() == limit ? list.get(limit - 1).getName() : null;
+ PageSet<StorageMetadata> pageSet = new PageSetImpl<StorageMetadata>(list, marker);
+ if (options.isDetailed()) {
+ return fetchMetadata.setContainerName(container).apply(pageSet);
+ }
+ return pageSet;
+ }
+ }
+
+ @Override
+ public boolean blobExists(String container, String name) {
+ return blobMetadata(container, name) != null;
+ }
+
+ @Override
+ public String putBlob(String container, Blob blob) {
+ return putBlob(container, blob, PutOptions.NONE);
+ }
+
+ @Override
+ public String putBlob(String container, Blob blob, PutOptions options) {
+ if (options.isMultipart()) {
+ throw new UnsupportedOperationException();
+ }
+ ObjectApi objectApi = api.objectApiInRegionForContainer(regionId(), container);
+ return objectApi.replace(blob.getMetadata().getName(), blob.getPayload(), blob.getMetadata().getUserMetadata());
+ }
+
+ @Override
+ public BlobMetadata blobMetadata(String container, String name) {
+ SwiftObject object = api.objectApiInRegionForContainer(regionId(), container).head(name);
+ if (object == null) {
+ return null;
+ }
+ return toBlobMetadata(container).apply(object);
+ }
+
+ @Override
+ public Blob getBlob(String container, String name, GetOptions options) {
+ ObjectApi objectApi = api.objectApiInRegionForContainer(regionId(), container);
+ SwiftObject object = objectApi.get(name, toGetOptions.apply(options));
+ if (object == null) {
+ return null;
+ }
+ Blob blob = new BlobImpl(toBlobMetadata(container).apply(object));
+ blob.setPayload(object.payload());
+ return blob;
+ }
+
+ @Override
+ public void removeBlob(String container, String name) {
+ api.objectApiInRegionForContainer(regionId(), container).delete(name);
+ }
+
+ @Override
+ protected boolean deleteAndVerifyContainerGone(String container) {
+ api.containerApiInRegion(regionId()).deleteIfEmpty(container);
+ containerCache.invalidate(container);
+ return true;
+ }
+
+ protected final LoadingCache<String, Optional<Container>> containerCache = CacheBuilder.newBuilder().build(
+ new CacheLoader<String, Optional<Container>>() {
+ public Optional<Container> load(String container) {
+ return Optional.fromNullable(api.containerApiInRegion(regionId()).get(container));
+ }
+ });
+
+ protected Function<SwiftObject, MutableBlobMetadata> toBlobMetadata(String container) {
+ return new ToBlobMetadata(containerCache.getUnchecked(container).get());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedTemporaryUrlBlobSigner.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedTemporaryUrlBlobSigner.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedTemporaryUrlBlobSigner.java
new file mode 100644
index 0000000..81dce15
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedTemporaryUrlBlobSigner.java
@@ -0,0 +1,102 @@
+/*
+ * 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.blobstore;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Provider;
+
+import org.jclouds.blobstore.BlobRequestSigner;
+import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
+import org.jclouds.date.TimeStamp;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.Uris;
+import org.jclouds.http.options.GetOptions;
+import org.jclouds.location.Region;
+import org.jclouds.openstack.swift.v1.TemporaryUrlSigner;
+
+import com.google.common.base.Supplier;
+import com.google.inject.Inject;
+
+/**
+ * Uses {@link TemporaryUrlSigner} to sign requests for access to blobs. If no
+ * interval is supplied, it defaults to a year.
+ */
+public class RegionScopedTemporaryUrlBlobSigner implements BlobRequestSigner {
+ private static final long YEAR = TimeUnit.DAYS.toSeconds(365);
+ private final BlobToHttpGetOptions toGetOptions = new BlobToHttpGetOptions();
+
+ private final Supplier<TemporaryUrlSigner> signer;
+ private final Supplier<URI> storageUrl;
+ private final Provider<Long> timestamp;
+
+ @Inject
+ protected RegionScopedTemporaryUrlBlobSigner(Supplier<TemporaryUrlSigner> signer, @Region Supplier<URI> storageUrl,
+ @TimeStamp Provider<Long> timestamp) {
+ this.signer = signer;
+ this.storageUrl = storageUrl;
+ this.timestamp = timestamp;
+ }
+
+ @Override
+ public HttpRequest signGetBlob(String container, String name) {
+ return signGetBlob(container, name, YEAR);
+ }
+
+ @Override
+ public HttpRequest signGetBlob(String container, String name, long timeInSeconds) {
+ return sign("GET", container, name, GetOptions.NONE, timestamp.get() + timeInSeconds);
+ }
+
+ @Override
+ public HttpRequest signGetBlob(String container, String name, org.jclouds.blobstore.options.GetOptions options) {
+ return sign("GET", container, name, toGetOptions.apply(options), timestamp.get() + YEAR);
+ }
+
+ @Override
+ public HttpRequest signPutBlob(String container, Blob blob) {
+ return signPutBlob(container, blob, YEAR);
+ }
+
+ @Override
+ public HttpRequest signPutBlob(String container, Blob blob, long timeInSeconds) {
+ return sign("PUT", container, blob.getMetadata().getName(), GetOptions.NONE, timestamp.get() + timeInSeconds);
+ }
+
+ @Override
+ public HttpRequest signRemoveBlob(String container, String name) {
+ return sign("DELETE", container, name, GetOptions.NONE, timestamp.get() + YEAR);
+ }
+
+ private HttpRequest sign(String method, String container, String name, GetOptions options, long expires) {
+ checkNotNull(container, "container");
+ checkNotNull(name, "name");
+ URI url = Uris.uriBuilder(storageUrl.get()).appendPath(container).appendPath(name).build();
+ String signature = signer.get().sign(method, url.getPath(), expires);
+ return HttpRequest.builder()
+ .method(method)
+ .endpoint(url)
+ .addQueryParams(options.buildQueryParameters())
+ .addQueryParam("temp_url_sig", signature)
+ .addQueryParam("temp_url_expires", String.valueOf(expires))
+ .headers(options.buildRequestHeaders()).build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/config/SignUsingTemporaryUrls.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/config/SignUsingTemporaryUrls.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/config/SignUsingTemporaryUrls.java
new file mode 100644
index 0000000..91c753c
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/config/SignUsingTemporaryUrls.java
@@ -0,0 +1,78 @@
+/*
+ * 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.blobstore.config;
+
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+
+import java.net.URI;
+import java.util.Map;
+
+import javax.inject.Singleton;
+
+import org.jclouds.blobstore.BlobRequestSigner;
+import org.jclouds.date.TimeStamp;
+import org.jclouds.location.Region;
+import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.TemporaryUrlSigner;
+import org.jclouds.openstack.swift.v1.blobstore.RegionScopedTemporaryUrlBlobSigner;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.name.Named;
+
+public class SignUsingTemporaryUrls extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(BlobRequestSigner.class).to(RegionScopedTemporaryUrlBlobSigner.class);
+ }
+
+ @Provides
+ @TimeStamp
+ protected Long unixEpochTimestamp() {
+ return System.currentTimeMillis() / 1000;
+ }
+
+ @Provides
+ @Singleton
+ Supplier<TemporaryUrlSigner> regionScopedTemporaryUrlSigner(final SwiftApi api,
+ @Region final Supplier<String> defaultRegion, @Named(PROPERTY_SESSION_INTERVAL) final long seconds) {
+ return Suppliers.memoize(new Supplier<TemporaryUrlSigner>() {
+
+ @Override
+ public TemporaryUrlSigner get() {
+ return TemporaryUrlSigner.checkApiEvery(api.accountApiInRegion(defaultRegion.get()), seconds);
+ }
+ });
+ }
+
+ @Provides
+ @Singleton
+ @Region
+ Supplier<URI> storageUrl(@Region final Supplier<String> defaultRegion,
+ @Region final Supplier<Map<String, Supplier<URI>>> regionToUris) {
+ return Suppliers.memoize(new Supplier<URI>() {
+
+ @Override
+ public URI get() {
+ return regionToUris.get().get(defaultRegion.get()).get();
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/config/SwiftBlobStoreContextModule.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/config/SwiftBlobStoreContextModule.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/config/SwiftBlobStoreContextModule.java
new file mode 100644
index 0000000..4452cdd
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/config/SwiftBlobStoreContextModule.java
@@ -0,0 +1,34 @@
+/*
+ * 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.blobstore.config;
+
+import org.jclouds.blobstore.AsyncBlobStore;
+import org.jclouds.blobstore.BlobStore;
+import org.jclouds.blobstore.attr.ConsistencyModel;
+import org.jclouds.openstack.swift.v1.blobstore.RegionScopedSwiftBlobStore;
+import org.jclouds.openstack.swift.v1.blobstore.internal.SubmissionAsyncBlobStore;
+
+import com.google.inject.AbstractModule;
+
+public class SwiftBlobStoreContextModule extends AbstractModule {
+ @Override
+ protected void configure() {
+ bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
+ bind(AsyncBlobStore.class).to(SubmissionAsyncBlobStore.class);
+ bind(BlobStore.class).to(RegionScopedSwiftBlobStore.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToBlobMetadata.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToBlobMetadata.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToBlobMetadata.java
new file mode 100644
index 0000000..eda42aa
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToBlobMetadata.java
@@ -0,0 +1,71 @@
+/*
+ * 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.blobstore.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.io.BaseEncoding.base16;
+
+import org.jclouds.blobstore.domain.MutableBlobMetadata;
+import org.jclouds.blobstore.domain.StorageType;
+import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl;
+import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy;
+import org.jclouds.blobstore.strategy.internal.MarkersIfDirectoryReturnNameStrategy;
+import org.jclouds.openstack.swift.v1.domain.Container;
+import org.jclouds.openstack.swift.v1.domain.SwiftObject;
+
+import com.google.common.base.Function;
+
+public class ToBlobMetadata implements Function<SwiftObject, MutableBlobMetadata> {
+
+ private final IfDirectoryReturnNameStrategy ifDirectoryReturnName = new MarkersIfDirectoryReturnNameStrategy();
+ private final Container container;
+
+ public ToBlobMetadata(Container container) {
+ this.container = checkNotNull(container, "container");
+ }
+
+ @Override
+ public MutableBlobMetadata apply(SwiftObject from) {
+ if (from == null)
+ return null;
+ MutableBlobMetadata to = new MutableBlobMetadataImpl();
+ to.setContainer(container.name());
+ if (container.anybodyRead().isPresent()) {
+ to.setPublicUri(from.uri());
+ }
+ to.setUri(from.uri());
+ to.setETag(from.etag());
+ to.setName(from.name());
+ to.setLastModified(from.lastModified());
+ to.setContentMetadata(from.payload().getContentMetadata());
+ to.getContentMetadata().setContentMD5(base16().lowerCase().decode(from.etag()));
+ to.setUserMetadata(from.metadata());
+ String directoryName = ifDirectoryReturnName.execute(to);
+ if (directoryName != null) {
+ to.setName(directoryName);
+ to.setType(StorageType.RELATIVE_PATH);
+ } else {
+ to.setType(StorageType.BLOB);
+ }
+ return to;
+ }
+
+ @Override
+ public String toString() {
+ return "ObjectToBlobMetadata(" + container + ")";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToListContainerOptions.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToListContainerOptions.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToListContainerOptions.java
new file mode 100644
index 0000000..2650f5b
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToListContainerOptions.java
@@ -0,0 +1,52 @@
+/*
+ * 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.blobstore.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.jclouds.blobstore.options.ListContainerOptions;
+
+import com.google.common.base.Function;
+
+public class ToListContainerOptions implements
+ Function<ListContainerOptions, org.jclouds.openstack.swift.v1.options.ListContainerOptions> {
+
+ @Override
+ public org.jclouds.openstack.swift.v1.options.ListContainerOptions apply(ListContainerOptions from) {
+ checkNotNull(from, "set options to instance NONE instead of passing null");
+ org.jclouds.openstack.swift.v1.options.ListContainerOptions options = new org.jclouds.openstack.swift.v1.options.ListContainerOptions();
+ if ((from.getDir() == null) && (from.isRecursive())) {
+ options.prefix("");
+ }
+ if ((from.getDir() == null) && (!from.isRecursive())) {
+ options.path("");
+ }
+ if ((from.getDir() != null) && (from.isRecursive())) {
+ options.prefix(from.getDir().endsWith("/") ? from.getDir() : from.getDir() + "/");
+ }
+ if ((from.getDir() != null) && (!from.isRecursive())) {
+ options.path(from.getDir());
+ }
+ if (from.getMarker() != null) {
+ options.marker(from.getMarker());
+ }
+ if (from.getMaxResults() != null) {
+ options.limit(from.getMaxResults());
+ }
+ return options;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToResourceMetadata.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToResourceMetadata.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToResourceMetadata.java
new file mode 100644
index 0000000..6d12ce8
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToResourceMetadata.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.swift.v1.blobstore.functions;
+
+import org.jclouds.blobstore.domain.MutableStorageMetadata;
+import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.blobstore.domain.StorageType;
+import org.jclouds.blobstore.domain.internal.MutableStorageMetadataImpl;
+import org.jclouds.domain.Location;
+import org.jclouds.openstack.swift.v1.domain.Container;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+
+public class ToResourceMetadata implements Function<Container, StorageMetadata> {
+ private Supplier<Location> region;
+
+ public ToResourceMetadata(Supplier<Location> region) {
+ this.region = region;
+ }
+
+ @Override
+ public StorageMetadata apply(Container from) {
+ MutableStorageMetadata to = new MutableStorageMetadataImpl();
+ to.setName(from.name());
+ to.setLocation(region.get());
+ to.setType(StorageType.CONTAINER);
+ to.setUserMetadata(from.metadata());
+ return to;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToSwiftObject.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToSwiftObject.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToSwiftObject.java
new file mode 100644
index 0000000..aabf63c
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/functions/ToSwiftObject.java
@@ -0,0 +1,55 @@
+/*
+ * 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.blobstore.functions;
+
+import org.jclouds.blobstore.domain.BlobMetadata;
+import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.io.Payload;
+import org.jclouds.io.Payloads;
+import org.jclouds.openstack.swift.v1.domain.SwiftObject;
+import org.jclouds.openstack.swift.v1.domain.SwiftObject.Builder;
+
+import com.google.common.base.Function;
+
+public class ToSwiftObject implements Function<StorageMetadata, SwiftObject> {
+
+ @Override
+ public SwiftObject apply(StorageMetadata in) {
+ if (!(in instanceof BlobMetadata)) {
+ return null;
+ }
+ BlobMetadata from = BlobMetadata.class.cast(in);
+ Builder to = SwiftObject.builder();
+ to.name(from.getName());
+ to.etag(from.getETag());
+ to.lastModified(from.getLastModified());
+ long bytes = from.getContentMetadata().getContentLength();
+ String contentType = from.getContentMetadata().getContentType();
+ to.payload(payload(bytes, contentType));
+ to.metadata(from.getUserMetadata());
+ return to.build();
+ }
+
+ 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/cbac63e1/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/internal/SubmissionAsyncBlobStore.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/internal/SubmissionAsyncBlobStore.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/internal/SubmissionAsyncBlobStore.java
new file mode 100644
index 0000000..1d083b2
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/blobstore/internal/SubmissionAsyncBlobStore.java
@@ -0,0 +1,284 @@
+/*
+ * 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.blobstore.internal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.Constants.PROPERTY_USER_THREADS;
+
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.blobstore.AsyncBlobStore;
+import org.jclouds.blobstore.BlobStore;
+import org.jclouds.blobstore.BlobStoreContext;
+import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.domain.BlobBuilder;
+import org.jclouds.blobstore.domain.BlobMetadata;
+import org.jclouds.blobstore.domain.PageSet;
+import org.jclouds.blobstore.domain.StorageMetadata;
+import org.jclouds.blobstore.options.CreateContainerOptions;
+import org.jclouds.blobstore.options.GetOptions;
+import org.jclouds.blobstore.options.ListContainerOptions;
+import org.jclouds.blobstore.options.PutOptions;
+import org.jclouds.domain.Location;
+
+import com.google.common.collect.ForwardingObject;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+/**
+ * Adapter that allows you to reuse an existing {@link BlobStore} to implement
+ * the deprecated {@link AsyncBlobStore} interface.
+ *
+ * @deprecated will be removed in jclouds 1.7, as async interfaces are no longer
+ * supported. Please use {@link BlobStore}
+ */
+@Deprecated
+public class SubmissionAsyncBlobStore extends ForwardingObject implements AsyncBlobStore {
+ private final BlobStore blobstore;
+ private final ListeningExecutorService executor;
+
+ @Inject
+ SubmissionAsyncBlobStore(BlobStore blobstore, @Named(PROPERTY_USER_THREADS) ListeningExecutorService executor) {
+ this.blobstore = checkNotNull(blobstore, "blobstore");
+ this.executor = checkNotNull(executor, "executor");
+ }
+
+ @Override
+ protected BlobStore delegate() {
+ return blobstore;
+ }
+
+ @Override
+ public BlobStoreContext getContext() {
+ return delegate().getContext();
+ }
+
+ @Override
+ public BlobBuilder blobBuilder(String name) {
+ return delegate().blobBuilder(name);
+ }
+
+ @Override
+ public ListenableFuture<Set<? extends Location>> listAssignableLocations() {
+ return executor.submit(new Callable<Set<? extends Location>>() {
+ public Set<? extends Location> call() {
+ return delegate().listAssignableLocations();
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<PageSet<? extends StorageMetadata>> list() {
+ return executor.submit(new Callable<PageSet<? extends StorageMetadata>>() {
+ public PageSet<? extends StorageMetadata> call() {
+ return delegate().list();
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Boolean> containerExists(final String container) {
+ return executor.submit(new Callable<Boolean>() {
+ public Boolean call() {
+ return delegate().containerExists(container);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Boolean> createContainerInLocation(final Location location, final String container) {
+ return executor.submit(new Callable<Boolean>() {
+ public Boolean call() {
+ return delegate().createContainerInLocation(location, container);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Boolean> createContainerInLocation(final Location location, final String container,
+ final CreateContainerOptions options) {
+ return executor.submit(new Callable<Boolean>() {
+ public Boolean call() {
+ return delegate().createContainerInLocation(location, container, options);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<PageSet<? extends StorageMetadata>> list(final String container) {
+ return executor.submit(new Callable<PageSet<? extends StorageMetadata>>() {
+ public PageSet<? extends StorageMetadata> call() {
+ return delegate().list(container);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<PageSet<? extends StorageMetadata>> list(final String container,
+ final ListContainerOptions options) {
+ return executor.submit(new Callable<PageSet<? extends StorageMetadata>>() {
+ public PageSet<? extends StorageMetadata> call() {
+ return delegate().list(container, options);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Void> clearContainer(final String container) {
+ return executor.submit(new Callable<Void>() {
+ public Void call() {
+ delegate().clearContainer(container);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Void> clearContainer(final String container, final ListContainerOptions options) {
+ return executor.submit(new Callable<Void>() {
+ public Void call() {
+ delegate().clearContainer(container, options);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Void> deleteContainer(final String container) {
+ return executor.submit(new Callable<Void>() {
+ public Void call() {
+ delegate().deleteContainer(container);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Boolean> directoryExists(final String container, final String directory) {
+ return executor.submit(new Callable<Boolean>() {
+ public Boolean call() {
+ return delegate().directoryExists(container, directory);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Void> createDirectory(final String container, final String directory) {
+ return executor.submit(new Callable<Void>() {
+ public Void call() {
+ delegate().createDirectory(container, directory);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Void> deleteDirectory(final String containerName, final String name) {
+ return executor.submit(new Callable<Void>() {
+ public Void call() {
+ delegate().deleteDirectory(containerName, name);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Boolean> blobExists(final String container, final String name) {
+ return executor.submit(new Callable<Boolean>() {
+ public Boolean call() {
+ return delegate().blobExists(container, name);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<String> putBlob(final String container, final Blob blob) {
+ return executor.submit(new Callable<String>() {
+ public String call() {
+ return delegate().putBlob(container, blob);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<String> putBlob(final String container, final Blob blob, final PutOptions options) {
+ return executor.submit(new Callable<String>() {
+ public String call() {
+ return delegate().putBlob(container, blob, options);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<BlobMetadata> blobMetadata(final String container, final String key) {
+ return executor.submit(new Callable<BlobMetadata>() {
+ public BlobMetadata call() {
+ return delegate().blobMetadata(container, key);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Blob> getBlob(final String container, final String key) {
+ return executor.submit(new Callable<Blob>() {
+ public Blob call() {
+ return delegate().getBlob(container, key);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Blob> getBlob(final String container, final String key, final GetOptions options) {
+ return executor.submit(new Callable<Blob>() {
+ public Blob call() {
+ return delegate().getBlob(container, key, options);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Void> removeBlob(final String container, final String key) {
+ return executor.submit(new Callable<Void>() {
+ public Void call() {
+ delegate().removeBlob(container, key);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Long> countBlobs(final String container) {
+ return executor.submit(new Callable<Long>() {
+ public Long call() {
+ return delegate().countBlobs(container);
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Long> countBlobs(final String container, final ListContainerOptions options) {
+ return executor.submit(new Callable<Long>() {
+ public Long call() {
+ return delegate().countBlobs(container, options);
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
new file mode 100644
index 0000000..39f0a0f
--- /dev/null
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.blobstore.integration;
+
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+
+import java.util.Properties;
+
+import org.jclouds.blobstore.domain.Blob;
+import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest;
+import org.testng.SkipException;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+@Test(groups = "live")
+public class SwiftBlobIntegrationLiveTest extends BaseBlobIntegrationTest {
+ public SwiftBlobIntegrationLiveTest() {
+ provider = "openstack-swift";
+ }
+
+ @Override
+ protected Properties setupProperties() {
+ Properties props = super.setupProperties();
+ setIfTestSystemPropertyPresent(props, CREDENTIAL_TYPE);
+ return props;
+ }
+
+ // Object/Container name contains forbidden chars from "<>
+ @Override
+ @DataProvider(name = "delete")
+ public Object[][] createData() {
+ return new Object[][] { { "normal" }, { "sp ace" }, { "qu?stion" }, { "unic₪de" }, { "path/foo" }, { "colon:" },
+ { "asteri*k" }, { "p|pe" } };
+ }
+
+ @Override
+ public void testGetTwoRanges() {
+ throw new SkipException("unsupported in swift");
+ }
+
+ @Override
+ public void testCreateBlobWithExpiry() throws InterruptedException {
+ throw new SkipException("unsupported in swift");
+ }
+
+ @Test(groups = { "integration", "live" })
+ public void testGetIfUnmodifiedSince() throws InterruptedException {
+ throw new SkipException("unsupported in swift");
+ }
+
+ @Override
+ protected int getIncorrectContentMD5StatusCode() {
+ return 422;
+ }
+
+ @Override
+ protected void checkContentLanguage(Blob blob, String contentLanguage) {
+ assert blob.getPayload().getContentMetadata().getContentLanguage() == null;
+ assert blob.getMetadata().getContentMetadata().getContentLanguage() == null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
new file mode 100644
index 0000000..f7b6b00
--- /dev/null
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.swift.v1.blobstore.integration;
+
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+
+import java.util.Properties;
+
+import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live")
+public class SwiftBlobLiveTest extends BaseBlobLiveTest {
+ public SwiftBlobLiveTest() {
+ provider = "openstack-swift";
+ }
+
+ @Override
+ protected Properties setupProperties() {
+ Properties props = super.setupProperties();
+ setIfTestSystemPropertyPresent(props, CREDENTIAL_TYPE);
+ return props;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
new file mode 100644
index 0000000..36fc024
--- /dev/null
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.swift.v1.blobstore.integration;
+
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+
+import java.util.Properties;
+
+import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live")
+public class SwiftBlobSignerLiveTest extends BaseBlobSignerLiveTest {
+ public SwiftBlobSignerLiveTest() {
+ provider = "openstack-swift";
+ }
+
+ @Override
+ protected Properties setupProperties() {
+ Properties props = super.setupProperties();
+ setIfTestSystemPropertyPresent(props, CREDENTIAL_TYPE);
+ return props;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
new file mode 100644
index 0000000..4e682f8
--- /dev/null
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.blobstore.integration;
+
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Properties;
+
+import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live")
+public class SwiftContainerIntegrationLiveTest extends BaseContainerIntegrationTest {
+ public SwiftContainerIntegrationLiveTest() {
+ provider = "openstack-swift";
+ }
+
+ @Override
+ protected Properties setupProperties() {
+ Properties props = super.setupProperties();
+ setIfTestSystemPropertyPresent(props, CREDENTIAL_TYPE);
+ return props;
+ }
+
+ @Override
+ public void testListRootUsesDelimiter() throws InterruptedException {
+ try {
+ super.testListRootUsesDelimiter();
+ } catch (AssertionError e) {
+ // swift doesn't have the "common prefixes" in the response that s3
+ // does. If we wanted this to pass, we'd need to create
+ // pseudo-directories implicitly, which is costly and troublesome. It
+ // is better to fail this assertion.
+ assertTrue(e.getMessage().matches(".*16.* but .*15.*"), e.getMessage());
+ // ^^ squishy regex to deal with various formats of testng messages.
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
new file mode 100644
index 0000000..8f5ab6c
--- /dev/null
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.swift.v1.blobstore.integration;
+
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+
+import java.util.Properties;
+
+import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live")
+public class SwiftContainerLiveTest extends BaseContainerLiveTest {
+ public SwiftContainerLiveTest() {
+ provider = "openstack-swift";
+ }
+
+ @Override
+ protected Properties setupProperties() {
+ Properties props = super.setupProperties();
+ setIfTestSystemPropertyPresent(props, CREDENTIAL_TYPE);
+ return props;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
new file mode 100644
index 0000000..fa9a734
--- /dev/null
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.swift.v1.blobstore.integration;
+
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+
+import java.util.Properties;
+
+import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live")
+public class SwiftServiceIntegrationLiveTest extends BaseServiceIntegrationTest {
+ public SwiftServiceIntegrationLiveTest() {
+ provider = "openstack-swift";
+ }
+
+ @Override
+ protected Properties setupProperties() {
+ Properties props = super.setupProperties();
+ setIfTestSystemPropertyPresent(props, CREDENTIAL_TYPE);
+ return props;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/cbac63e1/openstack-swift/src/test/resources/logback.xml
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/resources/logback.xml b/openstack-swift/src/test/resources/logback.xml
index 990ca22..ce891f1 100644
--- a/openstack-swift/src/test/resources/logback.xml
+++ b/openstack-swift/src/test/resources/logback.xml
@@ -51,10 +51,12 @@
<appender-ref ref="FILE" />
</logger>
+<!--
<logger name="jclouds.wire">
<level value="DEBUG" />
<appender-ref ref="WIREFILE" />
</logger>
+-->
<logger name="jclouds.headers">
<level value="DEBUG" />
[2/3] git commit: JCLOUDS-298. expose container metadata via
ObjectList and port Object PUT code from legacy codebase
Posted by ad...@apache.org.
JCLOUDS-298. expose container metadata via ObjectList and port Object PUT code from legacy codebase
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/0426ebf0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/0426ebf0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/0426ebf0
Branch: refs/heads/master
Commit: 0426ebf0c00113f3affc608c2ba83da7bb5554be
Parents: 523b134
Author: Adrian Cole <ad...@gmail.com>
Authored: Sun Sep 29 23:49:50 2013 -0700
Committer: Adrian Cole <ad...@gmail.com>
Committed: Mon Sep 30 00:16:17 2013 -0700
----------------------------------------------------------------------
.../openstack/swift/v1/binders/SetPayload.java | 49 ++++++++++++++++++++
.../openstack/swift/v1/domain/ObjectList.java | 47 +++++++++++++++++++
.../openstack/swift/v1/features/BulkApi.java | 2 +-
.../openstack/swift/v1/features/ObjectApi.java | 22 +++------
.../functions/ParseObjectListFromResponse.java | 21 ++++++---
.../swift/v1/features/ObjectApiLiveTest.java | 5 +-
.../swift/v1/features/ObjectApiMockTest.java | 16 ++++---
.../swift/v1/internal/BaseSwiftApiLiveTest.java | 21 +++++----
8 files changed, 142 insertions(+), 41 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/0426ebf0/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/SetPayload.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/SetPayload.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/SetPayload.java
new file mode 100644
index 0000000..70aa6f0
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/binders/SetPayload.java
@@ -0,0 +1,49 @@
+/*
+ * 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.io.BaseEncoding.base16;
+import static com.google.common.net.HttpHeaders.ETAG;
+import static com.google.common.net.HttpHeaders.TRANSFER_ENCODING;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpRequest.Builder;
+import org.jclouds.io.Payload;
+import org.jclouds.rest.Binder;
+
+public class SetPayload implements Binder {
+ @SuppressWarnings("unchecked")
+ @Override
+ public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+ Builder<?> builder = request.toBuilder();
+ Payload payload = Payload.class.cast(input);
+ Long contentLength = payload.getContentMetadata().getContentLength();
+ if (contentLength != null && contentLength >= 0) {
+ checkArgument(contentLength <= 5l * 1024 * 1024 * 1024, "maximum size for put object is 5GB, %s",
+ contentLength);
+ } else {
+ builder.replaceHeader(TRANSFER_ENCODING, "chunked").build();
+ }
+ byte[] md5 = payload.getContentMetadata().getContentMD5();
+ if (md5 != null) {
+ // Swift will validate the md5, if placed as an ETag header
+ builder.replaceHeader(ETAG, base16().lowerCase().encode(md5));
+ }
+ return (R) builder.payload(payload).build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/0426ebf0/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
new file mode 100644
index 0000000..350e8e1
--- /dev/null
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/domain/ObjectList.java
@@ -0,0 +1,47 @@
+/*
+ * 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.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import com.google.common.collect.ForwardingList;
+
+public class ObjectList extends ForwardingList<SwiftObject> {
+
+ public static ObjectList create(List<SwiftObject> objects, Container container) {
+ return new ObjectList(objects, container);
+ }
+
+ private final List<SwiftObject> objects;
+ private final Container container;
+
+ protected ObjectList(List<SwiftObject> objects, Container container) {
+ this.objects = checkNotNull(objects, "objects");
+ this.container = checkNotNull(container, "container");
+ }
+
+ public Container container() {
+ return container;
+ }
+
+ @Override
+ protected List<SwiftObject> delegate() {
+ return objects;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/0426ebf0/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
index 0cc4546..60eb851 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
@@ -33,9 +33,9 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.io.Payload;
import org.jclouds.io.Payloads;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.swift.v1.binders.SetPayload;
import org.jclouds.openstack.swift.v1.domain.BulkDeleteResponse;
import org.jclouds.openstack.swift.v1.domain.ExtractArchiveResponse;
-import org.jclouds.openstack.swift.v1.features.ObjectApi.SetPayload;
import org.jclouds.rest.Binder;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.QueryParams;
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/0426ebf0/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 ebcc41b..14ce2f4 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
@@ -30,31 +30,28 @@ import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
-import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.http.HttpRequest;
import org.jclouds.http.options.GetOptions;
import org.jclouds.io.Payload;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindObjectMetadataToHeaders;
import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveObjectMetadataToHeaders;
+import org.jclouds.openstack.swift.v1.binders.SetPayload;
+import org.jclouds.openstack.swift.v1.domain.ObjectList;
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.openstack.swift.v1.options.ListContainerOptions;
-import org.jclouds.rest.Binder;
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;
-
/**
* @see <a href=
* "http://docs.openstack.org/api/openstack-object-storage/1.0/content/storage-object-services.html"
@@ -67,15 +64,16 @@ public interface ObjectApi {
/**
* Lists up to 10,000 objects.
*
- * @return a list of existing storage objects ordered by name.
+ * @return a list of existing storage objects ordered by name or null.
*/
@Named("ListObjects")
@GET
@QueryParams(keys = "format", values = "json")
@ResponseParser(ParseObjectListFromResponse.class)
- @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+ @Fallback(NullOnNotFoundOr404.class)
@Path("/")
- FluentIterable<SwiftObject> list(ListContainerOptions options);
+ @Nullable
+ ObjectList list(ListContainerOptions options);
/**
* Creates or updates an object.
@@ -99,14 +97,6 @@ public interface ObjectApi {
String replace(@PathParam("objectName") String objectName, @BinderParam(SetPayload.class) Payload payload,
@BinderParam(BindObjectMetadataToHeaders.class) Map<String, String> metadata);
- static class SetPayload implements Binder {
- @SuppressWarnings("unchecked")
- @Override
- public <R extends HttpRequest> R bindToRequest(R request, Object input) {
- return (R) request.toBuilder().payload(Payload.class.cast(input)).build();
- }
- }
-
/**
* Gets the {@link SwiftObject} metadata without its
* {@link Payload#getInput() body}.
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/0426ebf0/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
index 589e192..5cfa562 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseObjectListFromResponse.java
@@ -27,13 +27,16 @@ 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.Container;
+import org.jclouds.openstack.swift.v1.domain.ObjectList;
import org.jclouds.openstack.swift.v1.domain.SwiftObject;
import org.jclouds.rest.InvocationContext;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.common.base.Function;
-import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Lists;
-public class ParseObjectListFromResponse implements Function<HttpResponse, FluentIterable<SwiftObject>>,
+public class ParseObjectListFromResponse implements Function<HttpResponse, ObjectList>,
InvocationContext<ParseObjectListFromResponse> {
private static final class InternalObject {
@@ -45,18 +48,21 @@ public class ParseObjectListFromResponse implements Function<HttpResponse, Fluen
}
private final ParseJson<List<InternalObject>> json;
+ private final ParseContainerFromHeaders parseContainer;
@Inject
- ParseObjectListFromResponse(ParseJson<List<InternalObject>> json) {
+ ParseObjectListFromResponse(ParseJson<List<InternalObject>> json, ParseContainerFromHeaders parseContainer) {
this.json = json;
+ this.parseContainer = parseContainer;
}
private ToSwiftObject toSwiftObject;
@Override
- public FluentIterable<SwiftObject> apply(HttpResponse from) {
- return FluentIterable.from(json.apply(from)) //
- .transform(toSwiftObject);
+ public ObjectList apply(HttpResponse from) {
+ List<SwiftObject> objects = Lists.transform(json.apply(from), toSwiftObject);
+ Container container = parseContainer.apply(from);
+ return ObjectList.create(objects, container);
}
static class ToSwiftObject implements Function<InternalObject, SwiftObject> {
@@ -79,12 +85,13 @@ public class ParseObjectListFromResponse implements Function<HttpResponse, Fluen
@Override
public ParseObjectListFromResponse setContext(HttpRequest request) {
+ parseContainer.name = GeneratedHttpRequest.class.cast(request).getCaller().get().getArgs().get(1).toString();
String containerUri = request.getEndpoint().toString();
int queryIndex = containerUri.indexOf('?');
if (queryIndex != -1) {
containerUri = containerUri.substring(0, queryIndex);
}
- this.toSwiftObject = new ToSwiftObject(containerUri);
+ toSwiftObject = new ToSwiftObject(containerUri);
return this;
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/0426ebf0/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 8dad19a..cfc7192 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/features/ObjectApiLiveTest.java
@@ -32,6 +32,7 @@ import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import org.jclouds.http.options.GetOptions;
+import org.jclouds.openstack.swift.v1.domain.ObjectList;
import org.jclouds.openstack.swift.v1.domain.SwiftObject;
import org.jclouds.openstack.swift.v1.internal.BaseSwiftApiLiveTest;
import org.jclouds.openstack.swift.v1.options.CreateContainerOptions;
@@ -40,7 +41,6 @@ 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;
/**
@@ -56,7 +56,8 @@ public class ObjectApiLiveTest extends BaseSwiftApiLiveTest {
public void list() throws Exception {
for (String regionId : api.configuredRegions()) {
ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName);
- FluentIterable<SwiftObject> response = objectApi.list(new ListContainerOptions());
+ ObjectList response = objectApi.list(new ListContainerOptions());
+ assertEquals(response.container(), api.containerApiInRegion(regionId).get(containerName));
assertNotNull(response);
for (SwiftObject object : response) {
checkObject(object);
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/0426ebf0/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 789ec00..3b54eac 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.jclouds.openstack.swift.v1.options.ListContainerOptions.Builder.marker;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+import static org.jclouds.openstack.swift.v1.features.ContainerApiMockTest.*;
import java.net.URI;
import java.util.Map;
@@ -32,6 +33,7 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.io.Payload;
import org.jclouds.io.Payloads;
import org.jclouds.openstack.swift.v1.SwiftApi;
+import org.jclouds.openstack.swift.v1.domain.ObjectList;
import org.jclouds.openstack.swift.v1.domain.SwiftObject;
import org.jclouds.openstack.swift.v1.internal.BaseSwiftMockTest;
import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
@@ -82,13 +84,16 @@ public class ObjectApiMockTest extends BaseSwiftMockTest {
public void list() throws Exception {
MockWebServer server = mockSwiftServer();
server.enqueue(new MockResponse().setBody(access));
- server.enqueue(new MockResponse().setBody(objectList));
+ server.enqueue(containerResponse() //
+ .addHeader("X-Container-Read", ".r:*,.rlistings") //
+ .setBody(objectList));
try {
SwiftApi api = swiftApi(server.getUrl("/").toString());
- ImmutableList<SwiftObject> objects = api.objectApiInRegionForContainer("DFW", "myContainer")
- .list(new ListContainerOptions()).toList();
+ ObjectList objects = api.objectApiInRegionForContainer("DFW", "myContainer").list(new ListContainerOptions());
assertEquals(objects, parsedObjectsForUrl(server.getUrl("/").toString()));
+ assertEquals(objects.container().name(), "myContainer");
+ assertTrue(objects.container().anybodyRead().get());
assertEquals(server.getRequestCount(), 2);
assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
@@ -102,12 +107,11 @@ public class ObjectApiMockTest extends BaseSwiftMockTest {
public void listOptions() throws Exception {
MockWebServer server = mockSwiftServer();
server.enqueue(new MockResponse().setBody(access));
- server.enqueue(new MockResponse().setBody(objectList));
+ server.enqueue(containerResponse().setBody(objectList));
try {
SwiftApi api = swiftApi(server.getUrl("/").toString());
- ImmutableList<SwiftObject> objects = api.objectApiInRegionForContainer("DFW", "myContainer")
- .list(marker("test")).toList();
+ ObjectList objects = api.objectApiInRegionForContainer("DFW", "myContainer").list(marker("test"));
assertEquals(objects, parsedObjectsForUrl(server.getUrl("/").toString()));
assertEquals(server.getRequestCount(), 2);
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/0426ebf0/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
index 491a5f6..8d8166e 100644
--- a/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
+++ b/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
@@ -18,17 +18,19 @@ package org.jclouds.openstack.swift.v1.internal;
import static com.google.common.base.Preconditions.checkState;
+import java.util.List;
import java.util.Properties;
import org.jclouds.apis.BaseApiLiveTest;
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
import org.jclouds.openstack.swift.v1.SwiftApi;
import org.jclouds.openstack.swift.v1.domain.BulkDeleteResponse;
+import org.jclouds.openstack.swift.v1.domain.ObjectList;
import org.jclouds.openstack.swift.v1.domain.SwiftObject;
import org.jclouds.openstack.swift.v1.options.ListContainerOptions;
import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
public class BaseSwiftApiLiveTest extends BaseApiLiveTest<SwiftApi> {
@@ -44,14 +46,15 @@ public class BaseSwiftApiLiveTest extends BaseApiLiveTest<SwiftApi> {
}
protected void deleteAllObjectsInContainer(String regionId, final String containerName) {
- ImmutableList<String> pathsToDelete = api.objectApiInRegionForContainer(regionId, containerName)
- .list(new ListContainerOptions()).transform(new Function<SwiftObject, String>() {
-
- public String apply(SwiftObject input) {
- return containerName + "/" + input.name();
- }
-
- }).toList();
+ ObjectList objects = api.objectApiInRegionForContainer(regionId, containerName).list(new ListContainerOptions());
+ if (objects == null) {
+ return;
+ }
+ List<String> pathsToDelete = Lists.transform(objects, new Function<SwiftObject, String>() {
+ public String apply(SwiftObject input) {
+ return containerName + "/" + input.name();
+ }
+ });
if (!pathsToDelete.isEmpty()) {
BulkDeleteResponse response = api.bulkApiInRegion(regionId).bulkDelete(pathsToDelete);
checkState(response.errors().isEmpty(), "Errors deleting paths %s: %s", pathsToDelete, response);
[3/3] git commit: JCLOUDS-306. expose Container.anybodyRead
Posted by ad...@apache.org.
JCLOUDS-306. expose Container.anybodyRead
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/523b1342
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/523b1342
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/523b1342
Branch: refs/heads/master
Commit: 523b134256a781e7c8a5aaf314301cee7f7bd702
Parents: fd3f8cd
Author: Adrian Cole <ad...@gmail.com>
Authored: Sun Sep 29 23:47:23 2013 -0700
Committer: Adrian Cole <ad...@gmail.com>
Committed: Mon Sep 30 00:16:17 2013 -0700
----------------------------------------------------------------------
.../openstack/swift/v1/domain/Container.java | 37 +++++++++++++++++---
.../v1/functions/ParseContainerFromHeaders.java | 3 +-
.../swift/v1/features/ContainerApiMockTest.java | 3 --
.../features/CreatePublicContainerLiveTest.java | 29 +++------------
4 files changed, 39 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/523b1342/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 cfee278..eda6a6b 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
@@ -25,9 +25,11 @@ import java.util.Map;
import java.util.Map.Entry;
import org.jclouds.openstack.swift.v1.features.ContainerApi;
+import org.jclouds.openstack.swift.v1.options.CreateContainerOptions;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
/**
@@ -40,13 +42,16 @@ public class Container implements Comparable<Container> {
private final String name;
private final long objectCount;
private final long bytesUsed;
+ private final Optional<Boolean> anybodyRead;
private final Map<String, String> metadata;
- @ConstructorProperties({ "name", "count", "bytes", "metadata" })
- protected Container(String name, long objectCount, long bytesUsed, Map<String, String> metadata) {
+ @ConstructorProperties({ "name", "count", "bytes", "anybodyRead", "metadata" })
+ protected Container(String name, long objectCount, long bytesUsed, Optional<Boolean> anybodyRead,
+ Map<String, String> metadata) {
this.name = checkNotNull(name, "name");
this.objectCount = objectCount;
this.bytesUsed = bytesUsed;
+ this.anybodyRead = anybodyRead == null ? Optional.<Boolean> absent() : anybodyRead;
this.metadata = metadata == null ? ImmutableMap.<String, String> of() : metadata;
}
@@ -63,6 +68,17 @@ public class Container implements Comparable<Container> {
}
/**
+ * Absent except in {@link ContainerApi#get(String) GetContainer} commands.
+ *
+ * When present, designates that the container is publicly readable.
+ *
+ * @see CreateContainerOptions#anybodyRead()
+ */
+ public Optional<Boolean> anybodyRead() {
+ return anybodyRead;
+ }
+
+ /**
* Empty except in {@link ContainerApi#get(String) GetContainer} commands.
*
* <h3>Note</h3>
@@ -92,7 +108,7 @@ public class Container implements Comparable<Container> {
@Override
public int hashCode() {
- return Objects.hashCode(name(), objectCount(), bytesUsed(), metadata());
+ return Objects.hashCode(name(), objectCount(), bytesUsed(), anybodyRead(), metadata());
}
@Override
@@ -101,10 +117,11 @@ public class Container implements Comparable<Container> {
}
protected ToStringHelper string() {
- return toStringHelper("") //
+ return toStringHelper("").omitNullValues() //
.add("name", name()) //
.add("objectCount", objectCount()) //
.add("bytesUsed", bytesUsed()) //
+ .add("anybodyRead", anybodyRead().orNull()) //
.add("metadata", metadata());
}
@@ -129,6 +146,7 @@ public class Container implements Comparable<Container> {
protected String name;
protected long objectCount;
protected long bytesUsed;
+ protected Optional<Boolean> anybodyRead = Optional.absent();
protected Map<String, String> metadata = ImmutableMap.of();
/**
@@ -156,6 +174,14 @@ public class Container implements Comparable<Container> {
}
/**
+ * @see Container#anybodyRead()
+ */
+ public Builder anybodyRead(Boolean anybodyRead) {
+ this.anybodyRead = Optional.fromNullable(anybodyRead);
+ return this;
+ }
+
+ /**
* Will lower-case all metadata keys due to a swift implementation
* decision.
*
@@ -171,13 +197,14 @@ public class Container implements Comparable<Container> {
}
public Container build() {
- return new Container(name, objectCount, bytesUsed, metadata);
+ return new Container(name, objectCount, bytesUsed, anybodyRead, metadata);
}
public Builder fromContainer(Container from) {
return name(from.name()) //
.objectCount(from.objectCount()) //
.bytesUsed(from.bytesUsed()) //
+ .anybodyRead(from.anybodyRead().orNull()) //
.metadata(from.metadata());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/523b1342/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
----------------------------------------------------------------------
diff --git a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
index e246af5..5fb3c9f 100644
--- a/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
+++ b/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/functions/ParseContainerFromHeaders.java
@@ -27,7 +27,7 @@ import com.google.common.base.Function;
public class ParseContainerFromHeaders implements Function<HttpResponse, Container>,
InvocationContext<ParseContainerFromHeaders> {
- private String name;
+ String name;
@Override
public Container apply(HttpResponse from) {
@@ -35,6 +35,7 @@ public class ParseContainerFromHeaders implements Function<HttpResponse, Contain
.name(name) //
.bytesUsed(Long.parseLong(from.getFirstHeaderOrNull("X-Container-Bytes-Used"))) //
.objectCount(Long.parseLong(from.getFirstHeaderOrNull("X-Container-Object-Count"))) //
+ .anybodyRead(".r:*,.rlistings".equals(from.getFirstHeaderOrNull("X-Container-Read"))) //
.metadata(EntriesWithoutMetaPrefix.INSTANCE.apply(from.getHeaders())).build();
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/523b1342/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 159021e..6431a99 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
@@ -36,9 +36,6 @@ 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 {
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/523b1342/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 83f586e..f6251d0 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,40 +16,22 @@
*/
package org.jclouds.openstack.swift.v1.features;
-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 static org.testng.Assert.assertTrue;
-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 anybodyReadObjectUri() throws Exception {
+ public void anybodyReadUpdatesMetadata() throws Exception {
for (String regionId : api.configuredRegions()) {
- api.containerApiInRegion(regionId).createIfAbsent(containerName, anybodyRead());
- api.containerApiInRegion(regionId).get(containerName);
-
- ObjectApi objectApi = api.objectApiInRegionForContainer(regionId, containerName);
- objectApi.replace(name, newStringPayload("swifty"), ImmutableMap.<String, String> of());
-
- InputStream publicStream = objectApi.get(name, new GetOptions()).uri().toURL().openStream();
-
- assertEquals(Strings2.toStringAndClose(publicStream), "swifty");
+ api.containerApiInRegion(regionId).createIfAbsent(name, anybodyRead());
+ assertTrue(api.containerApiInRegion(regionId).get(name).anybodyRead().get());
}
}
@@ -57,8 +39,7 @@ public class CreatePublicContainerLiveTest extends BaseSwiftApiLiveTest {
@AfterClass(groups = "live")
public void tearDown() {
for (String regionId : api.configuredRegions()) {
- api.objectApiInRegionForContainer(regionId, containerName).delete(name);
- api.containerApiInRegion(regionId).deleteIfEmpty(containerName);
+ api.containerApiInRegion(regionId).deleteIfEmpty(name);
}
super.tearDown();
}