Issue 430: PutOptions.multipart()

This commit is contained in:
Adrian Cole 2011-04-05 12:26:16 -07:00
parent 793740b9be
commit 2bfc84beeb
18 changed files with 157 additions and 29 deletions

View File

@ -52,6 +52,7 @@ import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseAsyncBlobStore; import org.jclouds.blobstore.internal.BaseAsyncBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -255,7 +256,8 @@ public class AtmosAsyncBlobStore extends BaseAsyncBlobStore {
} }
@Override @Override
public ListenableFuture<String> putBlobMultipart(String container, Blob blob) { public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options) {
// TODO implement options
return putBlob(container, blob); return putBlob(container, blob);
} }

View File

@ -44,6 +44,7 @@ import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseBlobStore; import org.jclouds.blobstore.internal.BaseBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -214,7 +215,8 @@ public class AtmosBlobStore extends BaseBlobStore {
* Since there is no etag support in atmos, we just return the path. * Since there is no etag support in atmos, we just return the path.
*/ */
@Override @Override
public String putBlobMultipart(String container, Blob blob) { public String putBlob(String container, Blob blob, PutOptions options) {
// TODO implement options
return putBlob(container, blob); return putBlob(container, blob);
} }

View File

@ -82,6 +82,7 @@ import org.jclouds.blobstore.internal.BaseAsyncBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.GetOptions; import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy; import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -663,7 +664,8 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore {
} }
@Override @Override
public ListenableFuture<String> putBlobMultipart(String container, Blob blob) { public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options) {
// TODO implement options
return putBlob(container, blob); return putBlob(container, blob);
} }

View File

@ -28,5 +28,5 @@ import org.jclouds.concurrent.Timeout;
* *
* @author Alfredo "Rainbowbreeze" Morresi * @author Alfredo "Rainbowbreeze" Morresi
*/ */
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) public interface FilesystemBlobStore extends BlobStore { @Timeout(duration = 2, timeUnit = TimeUnit.MINUTES) public interface FilesystemBlobStore extends BlobStore {
} }

View File

@ -41,6 +41,7 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseAsyncBlobStore; import org.jclouds.blobstore.internal.BaseAsyncBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -252,7 +253,8 @@ public class S3AsyncBlobStore extends BaseAsyncBlobStore {
} }
@Override @Override
public ListenableFuture<String> putBlobMultipart(String container, Blob blob) { public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options) {
// TODO implement options
return putBlob(container, blob); return putBlob(container, blob);
} }

View File

@ -38,6 +38,7 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseBlobStore; import org.jclouds.blobstore.internal.BaseBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -247,8 +248,9 @@ public class S3BlobStore extends BaseBlobStore {
* object * object
*/ */
@Override @Override
public String putBlobMultipart(String container, Blob blob) { public String putBlob(String container, Blob blob, PutOptions options) {
return sync.putObject(container, blob2Object.apply(blob)); // TODO implement options
return putBlob(container, blob);
} }
/** /**

View File

@ -41,6 +41,7 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseAsyncBlobStore; import org.jclouds.blobstore.internal.BaseAsyncBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -237,7 +238,8 @@ public class SwiftAsyncBlobStore extends BaseAsyncBlobStore {
} }
@Override @Override
public ListenableFuture<String> putBlobMultipart(String container, Blob blob) { public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options) {
// TODO implement options
return putBlob(container, blob); return putBlob(container, blob);
} }

View File

@ -38,6 +38,7 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseBlobStore; import org.jclouds.blobstore.internal.BaseBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -205,7 +206,8 @@ public class SwiftBlobStore extends BaseBlobStore {
* object * object
*/ */
@Override @Override
public String putBlobMultipart(String container, Blob blob) { public String putBlob(String container, Blob blob, PutOptions options) {
// TODO implement options
return putBlob(container, blob); return putBlob(container, blob);
} }

View File

@ -31,9 +31,9 @@ import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.GetOptions; import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import com.google.common.annotations.Beta;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
/** /**
@ -130,15 +130,14 @@ public interface AsyncBlobStore {
ListenableFuture<Boolean> blobExists(String container, String name); ListenableFuture<Boolean> blobExists(String container, String name);
/** /**
* @see BlobStore#putBlob * @see BlobStore#putBlob(String,Blob)
*/ */
ListenableFuture<String> putBlob(String container, Blob blob); ListenableFuture<String> putBlob(String container, Blob blob);
/** /**
* @see BlobStore#putBlobMultipart * @see BlobStore#putBlob(String,Blob,PutOptions)
*/ */
@Beta ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options);
ListenableFuture<String> putBlobMultipart(String container, Blob blob);
/** /**
* @see BlobStore#blobMetadata * @see BlobStore#blobMetadata

View File

@ -31,10 +31,9 @@ import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.GetOptions; import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
import com.google.common.annotations.Beta;
/** /**
* Synchronous access to a BlobStore such as Amazon S3 * Synchronous access to a BlobStore such as Amazon S3
* *
@ -214,20 +213,19 @@ public interface BlobStore {
/** /**
* Adds a {@code Blob} representing the data at location {@code container/blob.metadata.name} * Adds a {@code Blob} representing the data at location {@code container/blob.metadata.name}
* using multipart strategies. * options using multipart strategies.
* *
* @param container * @param container
* container to place the blob. * container to place the blob.
* @param blob * @param blob
* fully qualified name relative to the container. * fully qualified name relative to the container.
* @param options * @param options
* byte range or condition options * byte range options
* @return etag of the blob you uploaded, possibly null where etags are unsupported * @return etag of the blob you uploaded, possibly null where etags are unsupported
* @throws ContainerNotFoundException * @throws ContainerNotFoundException
* if the container doesn't exist * if the container doesn't exist
*/ */
@Beta String putBlob(String container, Blob blob, PutOptions options);
String putBlobMultipart(String container, Blob blob);
/** /**
* Retrieves the metadata of a {@code Blob} at location {@code container/name} * Retrieves the metadata of a {@code Blob} at location {@code container/name}

View File

@ -81,6 +81,7 @@ import org.jclouds.blobstore.internal.BaseAsyncBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.GetOptions; import org.jclouds.blobstore.options.GetOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy; import org.jclouds.blobstore.strategy.IfDirectoryReturnNameStrategy;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -689,8 +690,8 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
} }
@Override @Override
public ListenableFuture<String> putBlobMultipart(String container, Blob blob) { public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options) {
// TODO implement // TODO implement options
return putBlob(container, blob); return putBlob(container, blob);
} }

View File

@ -67,7 +67,7 @@ public class BindMapToHeadersWithPrefix implements Binder {
@Override @Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) { public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(checkNotNull(input, "input") instanceof Map, "this binder is only valid for Maps!"); checkArgument(checkNotNull(input, "input") instanceof Map<?,?>, "this binder is only valid for Maps!");
checkNotNull(request, "request"); checkNotNull(request, "request");
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -0,0 +1,109 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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
*
* 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.blobstore.options;
/**
* Contains options supported in the put blob operation. <h2>
* Usage</h2> The recommended way to instantiate a PutOptions object is to statically import
* PutOptions.* and invoke a static creation method followed by an instance mutator (if needed):
* <p/>
* <code>
* import static org.jclouds.blobstore.options.PutOptions.Builder.*
* eTag = blobStore.putBlob("container", blob, multipart());
* <code>
*
* @author Adrian Cole
*/
public class PutOptions implements Cloneable {
public static final ImmutablePutOptions NONE = new ImmutablePutOptions(new PutOptions());
private boolean multipart;
public PutOptions() {
}
PutOptions(boolean multipart) {
this.multipart = multipart;
}
public static class ImmutablePutOptions extends PutOptions {
private final PutOptions delegate;
public ImmutablePutOptions(PutOptions delegate) {
this.delegate = delegate;
}
@Override
public boolean isMultipart() {
return delegate.isMultipart();
}
@Override
public PutOptions multipart() {
throw new UnsupportedOperationException();
}
@Override
public PutOptions clone() {
return delegate.clone();
}
@Override
public String toString() {
return delegate.toString();
}
}
public boolean isMultipart() {
return multipart;
}
/**
* split large blobs into pieces, if supported by the provider
*/
public PutOptions multipart() {
this.multipart = true;
return this;
}
public static class Builder {
/**
* @see PutOptions#multipart()
*/
public static PutOptions multipart() {
PutOptions options = new PutOptions();
return options.multipart();
}
}
@Override
public PutOptions clone() {
return new PutOptions(multipart);
}
@Override
public String toString() {
return "[multipart=" + multipart + "]";
}
}

View File

@ -34,6 +34,7 @@ import org.jclouds.aws.s3.blobstore.strategy.AsyncMultipartUploadStrategy;
import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -74,7 +75,7 @@ public class AWSS3AsyncBlobStore extends S3AsyncBlobStore {
} }
@Override @Override
public ListenableFuture<String> putBlobMultipart(String container, Blob blob) { public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options) {
// need to use a provider if the strategy object is stateful // need to use a provider if the strategy object is stateful
return multipartUploadStrategy.get().execute(container, blob); return multipartUploadStrategy.get().execute(container, blob);
} }

View File

@ -30,6 +30,7 @@ import org.jclouds.aws.s3.blobstore.strategy.MultipartUploadStrategy;
import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContext;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.functions.BlobToHttpGetOptions; import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata; import org.jclouds.blobstore.strategy.internal.FetchBlobMetadata;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
@ -69,8 +70,8 @@ public class AWSS3BlobStore extends S3BlobStore {
} }
@Override @Override
public String putBlobMultipart(String container, Blob blob) { public String putBlob(String container, Blob blob, PutOptions options) {
// need to use a provider if the strategy object is stateful // need to use a provider if the strategy object is stateful
return multipartUploadStrategy.get().execute(container, blob); return multipartUploadStrategy.get().execute(container, blob);
} }
} }

View File

@ -36,6 +36,7 @@ import java.util.zip.GZIPInputStream;
import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStore;
import org.jclouds.blobstore.KeyNotFoundException; import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.http.BaseJettyTest; import org.jclouds.http.BaseJettyTest;
import org.jclouds.http.apachehc.config.ApacheHCHttpCommandExecutorServiceModule; import org.jclouds.http.apachehc.config.ApacheHCHttpCommandExecutorServiceModule;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
@ -153,7 +154,7 @@ public class AWSS3ClientLiveTest extends S3ClientLiveTest {
blobStore.createContainerInLocation(null, containerName); blobStore.createContainerInLocation(null, containerName);
Blob blob = blobStore.blobBuilder("const.txt") Blob blob = blobStore.blobBuilder("const.txt")
.payload(new File("target/const.txt")).build(); .payload(new File("target/const.txt")).build();
blobStore.putBlobMultipart(containerName, blob); blobStore.putBlob(containerName, blob, PutOptions.Builder.multipart());
} finally { } finally {
returnContainer(containerName); returnContainer(containerName);
} }

View File

@ -54,6 +54,7 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseAsyncBlobStore; import org.jclouds.blobstore.internal.BaseAsyncBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
import org.jclouds.concurrent.Futures; import org.jclouds.concurrent.Futures;
@ -246,7 +247,8 @@ public class AzureAsyncBlobStore extends BaseAsyncBlobStore {
} }
@Override @Override
public ListenableFuture<String> putBlobMultipart(String container, Blob blob) { public ListenableFuture<String> putBlob(String container, Blob blob, PutOptions options) {
// TODO implement options
return putBlob(container, blob); return putBlob(container, blob);
} }

View File

@ -48,6 +48,7 @@ import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
import org.jclouds.blobstore.internal.BaseBlobStore; import org.jclouds.blobstore.internal.BaseBlobStore;
import org.jclouds.blobstore.options.CreateContainerOptions; import org.jclouds.blobstore.options.CreateContainerOptions;
import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.options.PutOptions;
import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized; import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location; import org.jclouds.domain.Location;
@ -203,7 +204,8 @@ public class AzureBlobStore extends BaseBlobStore {
* object * object
*/ */
@Override @Override
public String putBlobMultipart(String container, Blob blob) { public String putBlob(String container, Blob blob, PutOptions options) {
// TODO implement options
return putBlob(container, blob); return putBlob(container, blob);
} }