mirror of https://github.com/apache/jclouds.git
Issue 109: changed existing behavior to use strategy pattern
git-svn-id: http://jclouds.googlecode.com/svn/trunk@1944 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
f78670f871
commit
16de6c839c
|
@ -141,8 +141,8 @@ public abstract class BlobStoreContextBuilder<S extends BlobStore<C, M, B>, C ex
|
||||||
this.containerMetadataType = containerMetadataType;
|
this.containerMetadataType = containerMetadataType;
|
||||||
this.blobMetadataType = blobMetadataType;
|
this.blobMetadataType = blobMetadataType;
|
||||||
this.blobType = blobType;
|
this.blobType = blobType;
|
||||||
modules.add(new BlobStoreMapsModule<S, C, M, B>(connectionType,
|
modules.add(BlobStoreMapsModule.Builder.newBuilder(connectionType,
|
||||||
containerMetadataType, blobMetadataType, blobType));
|
containerMetadataType, blobMetadataType, blobType).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -23,15 +23,18 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.blobstore;
|
package org.jclouds.blobstore;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
import org.jclouds.blobstore.internal.BlobMapImpl;
|
import org.jclouds.blobstore.internal.BlobMapImpl;
|
||||||
import org.jclouds.blobstore.internal.InputStreamMapImpl;
|
import org.jclouds.blobstore.internal.InputStreamMapImpl;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobsStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.internal.ContainerListGetAllBlobMetadataStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.internal.RetryOnNotFoundGetAllBlobsStrategy;
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Scopes;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
import com.google.inject.assistedinject.FactoryProvider;
|
import com.google.inject.assistedinject.FactoryProvider;
|
||||||
import com.google.inject.util.Types;
|
import com.google.inject.util.Types;
|
||||||
|
@ -39,23 +42,72 @@ import com.google.inject.util.Types;
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class BlobStoreMapsModule<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
public class BlobStoreMapsModule extends AbstractModule {
|
||||||
extends AbstractModule {
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private BlobStoreMapsModule(TypeLiteral blobMapFactoryType, TypeLiteral blobMapImplType,
|
||||||
|
TypeLiteral inputStreamMapFactoryType, TypeLiteral inputStreamMapImplType,
|
||||||
|
TypeLiteral getAllBlobsStrategyType, TypeLiteral getAllBlobsStrategyImplType,
|
||||||
|
TypeLiteral getAllBlobMetadataStrategyType,
|
||||||
|
TypeLiteral getAllBlobMetadataStrategyImplType) {
|
||||||
|
this.blobMapFactoryType = blobMapFactoryType;
|
||||||
|
this.blobMapImplType = blobMapImplType;
|
||||||
|
this.inputStreamMapFactoryType = inputStreamMapFactoryType;
|
||||||
|
this.inputStreamMapImplType = inputStreamMapImplType;
|
||||||
|
this.getAllBlobsStrategyType = getAllBlobsStrategyType;
|
||||||
|
this.getAllBlobsStrategyImplType = getAllBlobsStrategyImplType;
|
||||||
|
this.getAllBlobMetadataStrategyType = getAllBlobMetadataStrategyType;
|
||||||
|
this.getAllBlobMetadataStrategyImplType = getAllBlobMetadataStrategyImplType;
|
||||||
|
}
|
||||||
|
|
||||||
// code is unchecked here as we are getting types at runtime. Due to type erasure, we cannot pass
|
// code is unchecked here as we are getting types at runtime. Due to type erasure, we cannot pass
|
||||||
// generic types into provider methods. This is why we are sending in TypeLiterals.
|
// generic types into provider methods. This is why we are sending in TypeLiterals.
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private final TypeLiteral blobMapFactoryType;
|
protected final TypeLiteral blobMapFactoryType;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private final TypeLiteral blobMapImplType;
|
protected final TypeLiteral blobMapImplType;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private final TypeLiteral inputStreamMapFactoryType;
|
protected final TypeLiteral inputStreamMapFactoryType;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private final TypeLiteral inputStreamMapImplType;
|
protected final TypeLiteral inputStreamMapImplType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected final TypeLiteral getAllBlobsStrategyType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected final TypeLiteral getAllBlobsStrategyImplType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected final TypeLiteral getAllBlobMetadataStrategyType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected final TypeLiteral getAllBlobMetadataStrategyImplType;
|
||||||
|
|
||||||
@Inject
|
public static class Builder<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>> {
|
||||||
public BlobStoreMapsModule(TypeLiteral<S> connectionType, TypeLiteral<C> containerMetadataType,
|
@SuppressWarnings("unused")
|
||||||
|
private final TypeLiteral<S> connectionType;
|
||||||
|
private final TypeLiteral<C> containerMetadataType;
|
||||||
|
private final TypeLiteral<M> blobMetadataType;
|
||||||
|
private final TypeLiteral<B> blobType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private TypeLiteral blobMapFactoryType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private TypeLiteral blobMapImplType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private TypeLiteral inputStreamMapFactoryType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private TypeLiteral inputStreamMapImplType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private TypeLiteral getAllBlobsStrategyType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private TypeLiteral getAllBlobsStrategyImplType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private TypeLiteral getAllBlobMetadataStrategyType;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private TypeLiteral getAllBlobMetadataStrategyImplType;
|
||||||
|
|
||||||
|
private Builder(TypeLiteral<S> connectionType, TypeLiteral<C> containerMetadataType,
|
||||||
TypeLiteral<M> blobMetadataType, TypeLiteral<B> blobType) {
|
TypeLiteral<M> blobMetadataType, TypeLiteral<B> blobType) {
|
||||||
|
this.connectionType = connectionType;
|
||||||
|
this.containerMetadataType = containerMetadataType;
|
||||||
|
this.blobMetadataType = blobMetadataType;
|
||||||
|
this.blobType = blobType;
|
||||||
blobMapFactoryType = TypeLiteral.get(Types.newParameterizedTypeWithOwner(BlobMap.class,
|
blobMapFactoryType = TypeLiteral.get(Types.newParameterizedTypeWithOwner(BlobMap.class,
|
||||||
BlobMap.Factory.class, blobMetadataType.getType(), blobType.getType()));
|
BlobMap.Factory.class, blobMetadataType.getType(), blobType.getType()));
|
||||||
blobMapImplType = TypeLiteral.get(Types.newParameterizedType(BlobMapImpl.class,
|
blobMapImplType = TypeLiteral.get(Types.newParameterizedType(BlobMapImpl.class,
|
||||||
|
@ -63,18 +115,61 @@ public class BlobStoreMapsModule<S extends BlobStore<C, M, B>, C extends Contain
|
||||||
.getType(), blobType.getType()));
|
.getType(), blobType.getType()));
|
||||||
inputStreamMapFactoryType = TypeLiteral.get(Types.newParameterizedTypeWithOwner(
|
inputStreamMapFactoryType = TypeLiteral.get(Types.newParameterizedTypeWithOwner(
|
||||||
InputStreamMap.class, InputStreamMap.Factory.class, blobMetadataType.getType()));
|
InputStreamMap.class, InputStreamMap.Factory.class, blobMetadataType.getType()));
|
||||||
inputStreamMapImplType = TypeLiteral.get(Types.newParameterizedType(InputStreamMapImpl.class,
|
inputStreamMapImplType = TypeLiteral.get(Types.newParameterizedType(
|
||||||
connectionType.getType(), containerMetadataType.getType(), blobMetadataType
|
InputStreamMapImpl.class, connectionType.getType(), containerMetadataType
|
||||||
|
.getType(), blobMetadataType.getType(), blobType.getType()));
|
||||||
|
getAllBlobsStrategyType = TypeLiteral.get(Types.newParameterizedType(
|
||||||
|
GetAllBlobsStrategy.class, containerMetadataType.getType(), blobMetadataType
|
||||||
.getType(), blobType.getType()));
|
.getType(), blobType.getType()));
|
||||||
|
setGetAllBlobsStrategyImpl(RetryOnNotFoundGetAllBlobsStrategy.class);
|
||||||
|
|
||||||
|
getAllBlobMetadataStrategyType = TypeLiteral.get(Types.newParameterizedType(
|
||||||
|
GetAllBlobMetadataStrategy.class, containerMetadataType.getType(),
|
||||||
|
blobMetadataType.getType(), blobType.getType()));
|
||||||
|
getAllBlobMetadataStrategyImplType = TypeLiteral.get(Types.newParameterizedType(
|
||||||
|
ContainerListGetAllBlobMetadataStrategy.class, containerMetadataType.getType(),
|
||||||
|
blobMetadataType.getType(), blobType.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder<S, C, M, B> withGetAllBlobsStrategy(Class<?> getAllBlobsStrategyImplClass) {
|
||||||
|
setGetAllBlobsStrategyImpl(getAllBlobsStrategyImplClass);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setGetAllBlobsStrategyImpl(Class<?> getAllBlobsStrategyImplClass) {
|
||||||
|
getAllBlobsStrategyImplType = TypeLiteral.get(Types.newParameterizedType(
|
||||||
|
getAllBlobsStrategyImplClass, containerMetadataType.getType(), blobMetadataType
|
||||||
|
.getType(), blobType.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>> Builder<S, C, M, B> newBuilder(
|
||||||
|
TypeLiteral<S> connectionType, TypeLiteral<C> containerMetadataType,
|
||||||
|
TypeLiteral<M> blobMetadataType, TypeLiteral<B> blobType) {
|
||||||
|
return new Builder<S, C, M, B>(connectionType, containerMetadataType, blobMetadataType,
|
||||||
|
blobType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlobStoreMapsModule build() {
|
||||||
|
|
||||||
|
return new BlobStoreMapsModule(blobMapFactoryType, blobMapImplType,
|
||||||
|
inputStreamMapFactoryType, inputStreamMapImplType, getAllBlobsStrategyType,
|
||||||
|
getAllBlobsStrategyImplType, getAllBlobMetadataStrategyType,
|
||||||
|
getAllBlobMetadataStrategyImplType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(blobMapFactoryType).toProvider(
|
bind(blobMapFactoryType).toProvider(
|
||||||
FactoryProvider.newFactory(blobMapFactoryType, blobMapImplType));
|
FactoryProvider.newFactory(blobMapFactoryType, blobMapImplType))
|
||||||
|
.in(Scopes.SINGLETON);
|
||||||
bind(inputStreamMapFactoryType).toProvider(
|
bind(inputStreamMapFactoryType).toProvider(
|
||||||
FactoryProvider.newFactory(inputStreamMapFactoryType, inputStreamMapImplType));
|
FactoryProvider.newFactory(inputStreamMapFactoryType, inputStreamMapImplType)).in(
|
||||||
|
Scopes.SINGLETON);
|
||||||
|
bind(getAllBlobsStrategyType).to(getAllBlobsStrategyImplType).in(Scopes.SINGLETON);
|
||||||
|
bind(getAllBlobMetadataStrategyType).to(getAllBlobMetadataStrategyImplType).in(
|
||||||
|
Scopes.SINGLETON);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.blobstore;
|
package org.jclouds.blobstore.internal;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
@ -29,10 +29,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
import java.util.SortedSet;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -42,16 +40,17 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
|
import org.jclouds.blobstore.KeyNotFoundException;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||||
import org.jclouds.rest.BoundedList;
|
import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobsStrategy;
|
||||||
|
import org.jclouds.rest.BoundedSortedSet;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
|
@ -68,8 +67,10 @@ import com.google.inject.assistedinject.Assisted;
|
||||||
public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>, V> {
|
public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>, V> {
|
||||||
|
|
||||||
protected final BlobStore<C, M, B> connection;
|
protected final BlobStore<C, M, B> connection;
|
||||||
protected final String container;
|
protected final String containerName;
|
||||||
protected final Provider<B> blobFactory;
|
protected final Provider<B> blobFactory;
|
||||||
|
protected final GetAllBlobsStrategy<C, M, B> getAllBlobs;
|
||||||
|
protected final GetAllBlobMetadataStrategy<C, M, B> getAllBlobMetadata;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* maximum duration of an blob Request
|
* maximum duration of an blob Request
|
||||||
|
@ -87,32 +88,30 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BaseBlobMap(BlobStore<C, M, B> connection, Provider<B> blobFactory,
|
public BaseBlobMap(BlobStore<C, M, B> connection, Provider<B> blobFactory,
|
||||||
@Assisted String containerName) {
|
GetAllBlobsStrategy<C, M, B> getAllBlobs,
|
||||||
|
GetAllBlobMetadataStrategy<C, M, B> getAllBlobMetadata, @Assisted String containerName) {
|
||||||
this.connection = checkNotNull(connection, "connection");
|
this.connection = checkNotNull(connection, "connection");
|
||||||
this.container = checkNotNull(containerName, "container");
|
this.containerName = checkNotNull(containerName, "container");
|
||||||
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
|
this.blobFactory = checkNotNull(blobFactory, "blobFactory");
|
||||||
checkArgument(!container.equals(""), "container name must not be a blank string!");
|
this.getAllBlobs = checkNotNull(getAllBlobs, "getAllBlobs");
|
||||||
|
this.getAllBlobMetadata = checkNotNull(getAllBlobMetadata, "getAllBlobMetadata");
|
||||||
|
checkArgument(!containerName.equals(""), "container name must not be a blank string!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p/>
|
* <p/>
|
||||||
* This returns the number of keys in the {@link BoundedList}
|
* This returns the number of keys in the {@link BoundedSortedSet}
|
||||||
*
|
*
|
||||||
* @see BoundedList#getContents()
|
* @see BoundedSortedSet#getContents()
|
||||||
*/
|
*/
|
||||||
public int size() {
|
public int size() {
|
||||||
try {
|
return getAllBlobMetadata.execute(connection, containerName).size();
|
||||||
return refreshContainer().size();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
|
||||||
throw new BlobRuntimeException("Error getting size of container" + container, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean containsETag(byte[] eTag) throws InterruptedException, ExecutionException,
|
protected boolean containsETag(byte[] eTag) throws InterruptedException, ExecutionException,
|
||||||
TimeoutException {
|
TimeoutException {
|
||||||
for (BlobMetadata metadata : refreshContainer()) {
|
for (BlobMetadata metadata : getAllBlobMetadata.execute(connection, containerName)) {
|
||||||
if (Arrays.equals(eTag, metadata.getETag()))
|
if (Arrays.equals(eTag, metadata.getETag()))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -138,39 +137,10 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
||||||
*
|
*
|
||||||
* @see BlobStore#getBlob(String, String)
|
* @see BlobStore#getBlob(String, String)
|
||||||
*/
|
*/
|
||||||
protected Set<B> getAllObjects() {
|
protected Set<B> getAllBlobs() {
|
||||||
Set<B> objects = Sets.newHashSet();
|
|
||||||
Map<String, Future<B>> futureObjects = Maps.newHashMap();
|
|
||||||
for (String key : keySet()) {
|
|
||||||
futureObjects.put(key, connection.getBlob(container, key));
|
|
||||||
}
|
|
||||||
for (Entry<String, Future<B>> futureObjectEntry : futureObjects.entrySet()) {
|
|
||||||
try {
|
|
||||||
ifNotFoundRetryOtherwiseAddToSet(futureObjectEntry.getKey(), futureObjectEntry
|
|
||||||
.getValue(), objects);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
|
||||||
throw new BlobRuntimeException(String.format("Error getting value from blob %1$s",
|
|
||||||
container), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
return getAllBlobs.execute(connection, containerName);
|
||||||
return objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public void ifNotFoundRetryOtherwiseAddToSet(String key, Future<B> value, Set<B> objects)
|
|
||||||
throws InterruptedException, ExecutionException, TimeoutException {
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
try {
|
|
||||||
B object = value.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
|
||||||
object.getMetadata().setKey(key);
|
|
||||||
objects.add(object);
|
|
||||||
return;
|
|
||||||
} catch (KeyNotFoundException e) {
|
|
||||||
Thread.sleep(requestRetryMilliseconds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -190,8 +160,8 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException(String.format(
|
throw new BlobRuntimeException(String.format(
|
||||||
"Error searching for ETAG of value: [%2$s] in container:%1$s", container, value),
|
"Error searching for ETAG of value: [%2$s] in container:%1$s", containerName,
|
||||||
e);
|
value), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,65 +178,48 @@ public abstract class BaseBlobMap<C extends ContainerMetadata, M extends BlobMet
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
try {
|
Set<Future<Boolean>> deletes = Sets.newHashSet();
|
||||||
List<Future<Boolean>> deletes = Lists.newArrayList();
|
for (M md : getAllBlobMetadata.execute(connection, containerName)) {
|
||||||
for (String key : keySet()) {
|
deletes.add(connection.removeBlob(containerName, md.getKey()));
|
||||||
deletes.add(connection.removeBlob(container, key));
|
|
||||||
}
|
}
|
||||||
for (Future<Boolean> isdeleted : deletes)
|
for (Future<Boolean> isdeleted : deletes) {
|
||||||
|
try {
|
||||||
if (!isdeleted.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)) {
|
if (!isdeleted.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)) {
|
||||||
throw new BlobRuntimeException("failed to delete entry");
|
throw new BlobRuntimeException("Failed to delete blob in container: "
|
||||||
|
+ containerName);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException("Error clearing container" + container, e);
|
throw new BlobRuntimeException("Error deleting blob in container: " + containerName, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @throws ContainerNotFoundException
|
|
||||||
* when the container doesn't exist
|
|
||||||
*/
|
|
||||||
protected List<M> refreshContainer() throws InterruptedException, ExecutionException,
|
|
||||||
TimeoutException {
|
|
||||||
return connection.listBlobs(container).get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> keySet() {
|
public Set<String> keySet() {
|
||||||
try {
|
|
||||||
Set<String> keys = Sets.newHashSet();
|
Set<String> keys = Sets.newHashSet();
|
||||||
for (BlobMetadata object : refreshContainer())
|
for (BlobMetadata object : getAllBlobMetadata.execute(connection, containerName))
|
||||||
keys.add(object.getKey());
|
keys.add(object.getKey());
|
||||||
return keys;
|
return keys;
|
||||||
} catch (Exception e) {
|
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
|
||||||
throw new BlobRuntimeException("Error getting keys in container: " + container, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsKey(Object key) {
|
public boolean containsKey(Object key) {
|
||||||
try {
|
try {
|
||||||
return connection.blobMetadata(container, key.toString()) != null;
|
return connection.blobMetadata(containerName, key.toString()) != null;
|
||||||
} catch (KeyNotFoundException e) {
|
} catch (KeyNotFoundException e) {
|
||||||
return false;
|
return false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException(String.format("Error searching for %1$s:%2$s", container,
|
throw new BlobRuntimeException(String.format("Error searching for %1$s:%2$s",
|
||||||
key), e);
|
containerName, key), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return keySet().size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<M> listContainer() {
|
public SortedSet<M> listContainer() {
|
||||||
try {
|
return getAllBlobMetadata.execute(connection, containerName);
|
||||||
return refreshContainer();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
|
||||||
throw new BlobRuntimeException("Error getting container" + container, e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -23,10 +23,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.blobstore.internal;
|
package org.jclouds.blobstore.internal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -35,15 +33,17 @@ import java.util.concurrent.TimeUnit;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
|
|
||||||
import org.jclouds.blobstore.BaseBlobMap;
|
|
||||||
import org.jclouds.blobstore.BlobMap;
|
import org.jclouds.blobstore.BlobMap;
|
||||||
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.domain.BlobMetadata;
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobsStrategy;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,8 +59,9 @@ public class BlobMapImpl<S extends BlobStore<C, M, B>, C extends ContainerMetada
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public BlobMapImpl(S connection, Provider<B> blobFactory,
|
public BlobMapImpl(S connection, Provider<B> blobFactory,
|
||||||
@Assisted String containerName) {
|
GetAllBlobsStrategy<C, M, B> getAllBlobs,
|
||||||
super(connection, blobFactory, containerName);
|
GetAllBlobMetadataStrategy<C, M, B> getAllBlobMetadata, @Assisted String containerName) {
|
||||||
|
super(connection, blobFactory, getAllBlobs, getAllBlobMetadata, containerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,14 +114,14 @@ public class BlobMapImpl<S extends BlobStore<C, M, B>, C extends ContainerMetada
|
||||||
*/
|
*/
|
||||||
public B get(Object key) {
|
public B get(Object key) {
|
||||||
try {
|
try {
|
||||||
return connection.getBlob(container, key.toString()).get(requestTimeoutMilliseconds,
|
return connection.getBlob(containerName, key.toString()).get(requestTimeoutMilliseconds,
|
||||||
TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
} catch (KeyNotFoundException e) {
|
} catch (KeyNotFoundException e) {
|
||||||
return null;
|
return null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException(String.format("Error geting object %1$s:%2$s", container,
|
throw new BlobRuntimeException(String.format("Error geting object %1$s:%2$s",
|
||||||
key), e);
|
containerName, key), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,12 +133,12 @@ public class BlobMapImpl<S extends BlobStore<C, M, B>, C extends ContainerMetada
|
||||||
public B put(String key, B value) {
|
public B put(String key, B value) {
|
||||||
B returnVal = getLastValue(key);
|
B returnVal = getLastValue(key);
|
||||||
try {
|
try {
|
||||||
connection.putBlob(container, value)
|
connection.putBlob(containerName, value).get(requestTimeoutMilliseconds,
|
||||||
.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException(String.format("Error putting object %1$s:%2$s%n%3$s",
|
throw new BlobRuntimeException(String.format("Error putting object %1$s:%2$s%n%3$s",
|
||||||
container, key, value), e);
|
containerName, key, value), e);
|
||||||
}
|
}
|
||||||
return returnVal;
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
@ -149,16 +150,16 @@ public class BlobMapImpl<S extends BlobStore<C, M, B>, C extends ContainerMetada
|
||||||
*/
|
*/
|
||||||
public void putAll(Map<? extends String, ? extends B> map) {
|
public void putAll(Map<? extends String, ? extends B> map) {
|
||||||
try {
|
try {
|
||||||
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
|
Set<Future<byte[]>> puts = Sets.newHashSet();
|
||||||
for (B object : map.values()) {
|
for (B object : map.values()) {
|
||||||
puts.add(connection.putBlob(container, object));
|
puts.add(connection.putBlob(containerName, object));
|
||||||
}
|
}
|
||||||
for (Future<byte[]> put : puts)
|
for (Future<byte[]> put : puts)
|
||||||
// this will throw an exception if there was a problem
|
// this will throw an exception if there was a problem
|
||||||
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException("Error putting into containerName" + container, e);
|
throw new BlobRuntimeException("Error putting into containerName" + containerName, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,12 +171,12 @@ public class BlobMapImpl<S extends BlobStore<C, M, B>, C extends ContainerMetada
|
||||||
public B remove(Object key) {
|
public B remove(Object key) {
|
||||||
B old = getLastValue(key);
|
B old = getLastValue(key);
|
||||||
try {
|
try {
|
||||||
connection.removeBlob(container, key.toString()).get(requestTimeoutMilliseconds,
|
connection.removeBlob(containerName, key.toString()).get(requestTimeoutMilliseconds,
|
||||||
TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException(String.format("Error removing object %1$s:%2$s", container,
|
throw new BlobRuntimeException(String.format("Error removing object %1$s:%2$s",
|
||||||
key), e);
|
containerName, key), e);
|
||||||
}
|
}
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,6 @@ public class BlobMapImpl<S extends BlobStore<C, M, B>, C extends ContainerMetada
|
||||||
* @see #getAllObjects()
|
* @see #getAllObjects()
|
||||||
*/
|
*/
|
||||||
public Collection<B> values() {
|
public Collection<B> values() {
|
||||||
return getAllObjects();
|
return super.getAllBlobs();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,9 @@ package org.jclouds.blobstore.internal;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
@ -38,16 +36,18 @@ import java.util.concurrent.TimeUnit;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
|
|
||||||
import org.jclouds.blobstore.BaseBlobMap;
|
|
||||||
import org.jclouds.blobstore.BlobStore;
|
import org.jclouds.blobstore.BlobStore;
|
||||||
import org.jclouds.blobstore.InputStreamMap;
|
import org.jclouds.blobstore.InputStreamMap;
|
||||||
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.domain.BlobMetadata;
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobsStrategy;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,8 +64,9 @@ public class InputStreamMapImpl<S extends BlobStore<C, M, B>, C extends Containe
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public InputStreamMapImpl(S connection, Provider<B> blobFactory,
|
public InputStreamMapImpl(S connection, Provider<B> blobFactory,
|
||||||
@Assisted String container) {
|
GetAllBlobsStrategy<C, M, B> getAllBlobs,
|
||||||
super(connection, blobFactory, container);
|
GetAllBlobMetadataStrategy<C, M, B> getAllBlobMetadata, @Assisted String containerName) {
|
||||||
|
super(connection, blobFactory, getAllBlobs, getAllBlobMetadata, containerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,14 +76,14 @@ public class InputStreamMapImpl<S extends BlobStore<C, M, B>, C extends Containe
|
||||||
*/
|
*/
|
||||||
public InputStream get(Object o) {
|
public InputStream get(Object o) {
|
||||||
try {
|
try {
|
||||||
return (InputStream) (connection.getBlob(container, o.toString()).get(
|
return (InputStream) (connection.getBlob(containerName, o.toString()).get(
|
||||||
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).getData();
|
requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).getData();
|
||||||
} catch (KeyNotFoundException e) {
|
} catch (KeyNotFoundException e) {
|
||||||
return null;
|
return null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException(String
|
throw new BlobRuntimeException(String.format("Error geting object %1$s:%2$s",
|
||||||
.format("Error geting object %1$s:%2$s", container, o), e);
|
containerName, o), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,12 +95,12 @@ public class InputStreamMapImpl<S extends BlobStore<C, M, B>, C extends Containe
|
||||||
public InputStream remove(Object o) {
|
public InputStream remove(Object o) {
|
||||||
InputStream old = getLastValue(o);
|
InputStream old = getLastValue(o);
|
||||||
try {
|
try {
|
||||||
connection.removeBlob(container, o.toString()).get(requestTimeoutMilliseconds,
|
connection.removeBlob(containerName, o.toString()).get(requestTimeoutMilliseconds,
|
||||||
TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException(String.format("Error removing object %1$s:%2$s", container,
|
throw new BlobRuntimeException(String.format("Error removing object %1$s:%2$s",
|
||||||
o), e);
|
containerName, o), e);
|
||||||
}
|
}
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
@ -121,7 +122,7 @@ public class InputStreamMapImpl<S extends BlobStore<C, M, B>, C extends Containe
|
||||||
*/
|
*/
|
||||||
public Collection<InputStream> values() {
|
public Collection<InputStream> values() {
|
||||||
Collection<InputStream> values = new LinkedList<InputStream>();
|
Collection<InputStream> values = new LinkedList<InputStream>();
|
||||||
Set<B> objects = getAllObjects();
|
Set<B> objects = this.getAllBlobs.execute(connection, containerName);
|
||||||
for (B object : objects) {
|
for (B object : objects) {
|
||||||
values.add((InputStream) object.getData());
|
values.add((InputStream) object.getData());
|
||||||
}
|
}
|
||||||
|
@ -135,7 +136,7 @@ public class InputStreamMapImpl<S extends BlobStore<C, M, B>, C extends Containe
|
||||||
*/
|
*/
|
||||||
public Set<Map.Entry<String, InputStream>> entrySet() {
|
public Set<Map.Entry<String, InputStream>> entrySet() {
|
||||||
Set<Map.Entry<String, InputStream>> entrySet = new HashSet<Map.Entry<String, InputStream>>();
|
Set<Map.Entry<String, InputStream>> entrySet = new HashSet<Map.Entry<String, InputStream>>();
|
||||||
for (B object : getAllObjects()) {
|
for (B object : this.getAllBlobs.execute(connection, containerName)) {
|
||||||
entrySet.add(new Entry(object.getKey(), (InputStream) object.getData()));
|
entrySet.add(new Entry(object.getKey(), (InputStream) object.getData()));
|
||||||
}
|
}
|
||||||
return entrySet;
|
return entrySet;
|
||||||
|
@ -215,13 +216,13 @@ public class InputStreamMapImpl<S extends BlobStore<C, M, B>, C extends Containe
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void putAllInternal(Map<? extends String, ? extends Object> map) {
|
void putAllInternal(Map<? extends String, ? extends Object> map) {
|
||||||
try {
|
try {
|
||||||
List<Future<byte[]>> puts = new ArrayList<Future<byte[]>>();
|
Set<Future<byte[]>> puts = Sets.newHashSet();
|
||||||
for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
|
for (Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
|
||||||
B object = blobFactory.get();
|
B object = blobFactory.get();
|
||||||
object.getMetadata().setKey(entry.getKey());
|
object.getMetadata().setKey(entry.getKey());
|
||||||
object.setData(entry.getValue());
|
object.setData(entry.getValue());
|
||||||
object.generateMD5();
|
object.generateMD5();
|
||||||
puts.add(connection.putBlob(container, object));
|
puts.add(connection.putBlob(containerName, object));
|
||||||
// / ParamExtractor Funcion<?,String>
|
// / ParamExtractor Funcion<?,String>
|
||||||
// / response transformer set key on the way out.
|
// / response transformer set key on the way out.
|
||||||
// / ExceptionHandler convert 404 to NOT_FOUND
|
// / ExceptionHandler convert 404 to NOT_FOUND
|
||||||
|
@ -231,7 +232,7 @@ public class InputStreamMapImpl<S extends BlobStore<C, M, B>, C extends Containe
|
||||||
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
put.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException("Error putting into containerName" + container, e);
|
throw new BlobRuntimeException("Error putting into containerName" + containerName, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,13 +286,13 @@ public class InputStreamMapImpl<S extends BlobStore<C, M, B>, C extends Containe
|
||||||
InputStream returnVal = containsKey(s) ? get(s) : null;
|
InputStream returnVal = containsKey(s) ? get(s) : null;
|
||||||
object.setData(o);
|
object.setData(o);
|
||||||
object.generateMD5();
|
object.generateMD5();
|
||||||
connection.putBlob(container, object).get(requestTimeoutMilliseconds,
|
connection.putBlob(containerName, object).get(requestTimeoutMilliseconds,
|
||||||
TimeUnit.MILLISECONDS);
|
TimeUnit.MILLISECONDS);
|
||||||
return returnVal;
|
return returnVal;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
throw new BlobRuntimeException(String.format("Error adding object %1$s:%2$s", container,
|
throw new BlobRuntimeException(String.format("Error adding object %1$s:%2$s",
|
||||||
object), e);
|
containerName, object), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.blobstore.strategy;
|
||||||
|
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all blobs in the blobstore by the most efficient means possible.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public interface GetAllBlobMetadataStrategy<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>> {
|
||||||
|
|
||||||
|
SortedSet<M> execute(BlobStore<C, M, B> connection, String containerName);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.blobstore.strategy;
|
||||||
|
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all blobs in the blobstore by the most efficient means possible.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public interface GetAllBlobsStrategy<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>> {
|
||||||
|
|
||||||
|
SortedSet<B> execute(BlobStore<C, M, B> connection, String containerName);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.blobstore.strategy.internal;
|
||||||
|
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
|
import org.jclouds.blobstore.internal.BaseBlobMap.BlobRuntimeException;
|
||||||
|
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all blobs in the blobstore by the most efficient means possible.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ContainerListGetAllBlobMetadataStrategy<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||||
|
implements GetAllBlobMetadataStrategy<C, M, B> {
|
||||||
|
/**
|
||||||
|
* maximum duration of an blob Request
|
||||||
|
*/
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
|
||||||
|
protected long requestTimeoutMilliseconds = 30000;
|
||||||
|
|
||||||
|
public SortedSet<M> execute(BlobStore<C, M, B> connection, String container) {
|
||||||
|
try {
|
||||||
|
return connection.listBlobs(container).get(requestTimeoutMilliseconds,
|
||||||
|
TimeUnit.MILLISECONDS);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
|
throw new BlobRuntimeException("Error getting blob metadata in container: " + container, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.blobstore.strategy.internal;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
|
import org.jclouds.blobstore.KeyNotFoundException;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
|
import org.jclouds.blobstore.internal.BaseBlobMap.BlobRuntimeException;
|
||||||
|
import org.jclouds.blobstore.reference.BlobStoreConstants;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobsStrategy;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all blobs in the blobstore by the most efficient means possible.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class RetryOnNotFoundGetAllBlobsStrategy<C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>>
|
||||||
|
implements GetAllBlobsStrategy<C, M, B> {
|
||||||
|
/**
|
||||||
|
* maximum duration of an blob Request
|
||||||
|
*/
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_TIMEOUT)
|
||||||
|
public long requestTimeoutMilliseconds = 30000;
|
||||||
|
protected final GetAllBlobMetadataStrategy<C, M, B> getAllBlobMetadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* time to pause before retrying a transient failure
|
||||||
|
*/
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(BlobStoreConstants.PROPERTY_BLOBSTORE_RETRY)
|
||||||
|
protected long requestRetryMilliseconds = 10;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RetryOnNotFoundGetAllBlobsStrategy(GetAllBlobMetadataStrategy<C, M, B> getAllBlobMetadata) {
|
||||||
|
this.getAllBlobMetadata = getAllBlobMetadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SortedSet<B> execute(BlobStore<C, M, B> connection, String container) {
|
||||||
|
SortedSet<B> objects = Sets.<B> newTreeSet();
|
||||||
|
Map<String, Future<B>> futureObjects = Maps.newHashMap();
|
||||||
|
for (M md : getAllBlobMetadata.execute(connection, container)) {
|
||||||
|
futureObjects.put(md.getKey(), connection.getBlob(container, md.getKey()));
|
||||||
|
}
|
||||||
|
for (Entry<String, Future<B>> futureObjectEntry : futureObjects.entrySet()) {
|
||||||
|
try {
|
||||||
|
ifNotFoundRetryOtherwiseAddToSet(futureObjectEntry.getKey(), futureObjectEntry
|
||||||
|
.getValue(), objects);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Utils.<BlobRuntimeException> rethrowIfRuntimeOrSameType(e);
|
||||||
|
throw new BlobRuntimeException(String.format("Error getting value from blob %1$s",
|
||||||
|
container), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public void ifNotFoundRetryOtherwiseAddToSet(String key, Future<B> value, Set<B> objects)
|
||||||
|
throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
try {
|
||||||
|
B object = value.get(requestTimeoutMilliseconds, TimeUnit.MILLISECONDS);
|
||||||
|
object.getMetadata().setKey(key);
|
||||||
|
objects.add(object);
|
||||||
|
return;
|
||||||
|
} catch (KeyNotFoundException e) {
|
||||||
|
Thread.sleep(requestRetryMilliseconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.blobstore;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
|
import org.jclouds.blobstore.integration.config.StubBlobStoreConnectionModule;
|
||||||
|
import org.jclouds.blobstore.internal.BlobMapImpl;
|
||||||
|
import org.jclouds.blobstore.internal.InputStreamMapImpl;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobMetadataStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.GetAllBlobsStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.internal.ContainerListGetAllBlobMetadataStrategy;
|
||||||
|
import org.jclouds.blobstore.strategy.internal.RetryOnNotFoundGetAllBlobsStrategy;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "blobstore.BlobStoreMapsModuleTest")
|
||||||
|
public class BlobStoreMapsModuleTest {
|
||||||
|
|
||||||
|
public void testBuilderBuild() {
|
||||||
|
BlobStoreMapsModule module = BlobStoreMapsModule.Builder.newBuilder(
|
||||||
|
new TypeLiteral<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
}, new TypeLiteral<ContainerMetadata>() {
|
||||||
|
}, new TypeLiteral<BlobMetadata>() {
|
||||||
|
}, new TypeLiteral<Blob<BlobMetadata>>() {
|
||||||
|
}).build();
|
||||||
|
assertEquals(module.blobMapFactoryType,
|
||||||
|
new TypeLiteral<BlobMap.Factory<BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
});
|
||||||
|
assertEquals(
|
||||||
|
module.blobMapImplType,
|
||||||
|
new TypeLiteral<BlobMapImpl<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
});
|
||||||
|
assertEquals(module.inputStreamMapFactoryType,
|
||||||
|
new TypeLiteral<InputStreamMap.Factory<BlobMetadata>>() {
|
||||||
|
});
|
||||||
|
assertEquals(
|
||||||
|
module.inputStreamMapImplType,
|
||||||
|
new TypeLiteral<InputStreamMapImpl<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>, ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
});
|
||||||
|
assertEquals(
|
||||||
|
module.getAllBlobsStrategyType,
|
||||||
|
new TypeLiteral<GetAllBlobsStrategy<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
});
|
||||||
|
assertEquals(
|
||||||
|
module.getAllBlobsStrategyImplType,
|
||||||
|
new TypeLiteral<RetryOnNotFoundGetAllBlobsStrategy<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
});
|
||||||
|
assertEquals(
|
||||||
|
module.getAllBlobMetadataStrategyType,
|
||||||
|
new TypeLiteral<GetAllBlobMetadataStrategy<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
});
|
||||||
|
assertEquals(
|
||||||
|
module.getAllBlobMetadataStrategyImplType,
|
||||||
|
new TypeLiteral<ContainerListGetAllBlobMetadataStrategy<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInject() {
|
||||||
|
Injector i = Guice
|
||||||
|
.createInjector(
|
||||||
|
new StubBlobStoreConnectionModule(),
|
||||||
|
BlobStoreMapsModule.Builder
|
||||||
|
.newBuilder(
|
||||||
|
new TypeLiteral<BlobStore<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
}, new TypeLiteral<ContainerMetadata>() {
|
||||||
|
}, new TypeLiteral<BlobMetadata>() {
|
||||||
|
}, new TypeLiteral<Blob<BlobMetadata>>() {
|
||||||
|
}).build());
|
||||||
|
assertNotNull(i.getInstance(Key
|
||||||
|
.get(new TypeLiteral<BlobMap.Factory<BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
})));
|
||||||
|
assertNotNull(i.getInstance(Key.get(new TypeLiteral<InputStreamMap.Factory<BlobMetadata>>() {
|
||||||
|
})));
|
||||||
|
assertEquals(
|
||||||
|
i
|
||||||
|
.getInstance(
|
||||||
|
Key
|
||||||
|
.get(new TypeLiteral<GetAllBlobsStrategy<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
})).getClass(), RetryOnNotFoundGetAllBlobsStrategy.class);
|
||||||
|
assertEquals(
|
||||||
|
i
|
||||||
|
.getInstance(
|
||||||
|
Key
|
||||||
|
.get(new TypeLiteral<GetAllBlobMetadataStrategy<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
})).getClass(),
|
||||||
|
ContainerListGetAllBlobMetadataStrategy.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,9 +28,9 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
|
@ -56,10 +56,10 @@ import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.BeforeSuite;
|
import org.testng.annotations.BeforeSuite;
|
||||||
import org.testng.collections.Lists;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>> {
|
public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extends ContainerMetadata, M extends BlobMetadata, B extends Blob<M>> {
|
||||||
|
@ -171,7 +171,7 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final List<String> blackListContainers = Lists.newArrayList();
|
private static final Set<String> blackListContainers = Sets.newHashSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to delete all containers, runs up to two times
|
* Tries to delete all containers, runs up to two times
|
||||||
|
@ -182,7 +182,7 @@ public class BaseBlobStoreIntegrationTest<S extends BlobStore<C, M, B>, C extend
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
Iterable<ContainerMetadata> testContainers = Iterables.filter(
|
Iterable<ContainerMetadata> testContainers = Iterables.filter(
|
||||||
(List<ContainerMetadata>) context.getApi().listContainers(),
|
(SortedSet<ContainerMetadata>) context.getApi().listContainers(),
|
||||||
new Predicate<ContainerMetadata>() {
|
new Predicate<ContainerMetadata>() {
|
||||||
public boolean apply(ContainerMetadata input) {
|
public boolean apply(ContainerMetadata input) {
|
||||||
return input.getName().startsWith(CONTAINER_PREFIX.toLowerCase());
|
return input.getName().startsWith(CONTAINER_PREFIX.toLowerCase());
|
||||||
|
|
|
@ -21,27 +21,20 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
package org.jclouds.blobstore;
|
package org.jclouds.blobstore.internal;
|
||||||
|
|
||||||
import static org.easymock.EasyMock.expect;
|
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
|
||||||
import static org.easymock.classextension.EasyMock.createNiceMock;
|
|
||||||
import static org.easymock.classextension.EasyMock.replay;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.BlobMap;
|
||||||
|
import org.jclouds.blobstore.BlobStore;
|
||||||
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
|
import org.jclouds.blobstore.BlobStoreContextImpl;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.blobstore.domain.BlobMetadata;
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
import org.jclouds.blobstore.domain.ContainerMetadata;
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
import org.jclouds.blobstore.integration.StubBlobStoreContextBuilder;
|
import org.jclouds.blobstore.integration.StubBlobStoreContextBuilder;
|
||||||
import org.jclouds.blobstore.internal.InputStreamMapImpl;
|
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -105,41 +98,4 @@ public class BaseBlobMapTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testIfNotFoundRetryOtherwiseAddToSet() throws InterruptedException,
|
|
||||||
ExecutionException, TimeoutException {
|
|
||||||
Future<Blob<BlobMetadata>> futureObject = createMock(Future.class);
|
|
||||||
Blob<BlobMetadata> object = context.newBlob("key");
|
|
||||||
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andThrow(
|
|
||||||
new KeyNotFoundException());
|
|
||||||
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andReturn(
|
|
||||||
object);
|
|
||||||
replay(futureObject);
|
|
||||||
Set<Blob<BlobMetadata>> objects = new HashSet<Blob<BlobMetadata>>();
|
|
||||||
long time = System.currentTimeMillis();
|
|
||||||
map.ifNotFoundRetryOtherwiseAddToSet("key", futureObject, objects);
|
|
||||||
// should have retried once
|
|
||||||
assert System.currentTimeMillis() >= time + map.requestRetryMilliseconds;
|
|
||||||
assert objects.contains(object);
|
|
||||||
assert !objects.contains(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testIfNotFoundRetryOtherwiseAddToSetButNeverGetsIt() throws InterruptedException,
|
|
||||||
ExecutionException, TimeoutException {
|
|
||||||
Future<Blob<BlobMetadata>> futureObject = createMock(Future.class);
|
|
||||||
Blob object = createNiceMock(Blob.class);
|
|
||||||
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andThrow(
|
|
||||||
new KeyNotFoundException()).atLeastOnce();
|
|
||||||
replay(futureObject);
|
|
||||||
Set<Blob<BlobMetadata>> objects = new HashSet<Blob<BlobMetadata>>();
|
|
||||||
long time = System.currentTimeMillis();
|
|
||||||
map.ifNotFoundRetryOtherwiseAddToSet("key", futureObject, objects);
|
|
||||||
// should have retried thrice
|
|
||||||
assert System.currentTimeMillis() >= time + map.requestRetryMilliseconds * 3;
|
|
||||||
|
|
||||||
assert !objects.contains(object);
|
|
||||||
assert !objects.contains(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* 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.blobstore.strategy.internal;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.classextension.EasyMock.createMock;
|
||||||
|
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||||
|
import static org.easymock.classextension.EasyMock.replay;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.KeyNotFoundException;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.BlobMetadata;
|
||||||
|
import org.jclouds.blobstore.domain.ContainerMetadata;
|
||||||
|
import org.jclouds.blobstore.integration.StubBlobStoreContextBuilder;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Tests retry logic.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = { "unit" }, testName = "blobstore.RetryOnNotFoundGetAllBlobsStrategyTest")
|
||||||
|
public class RetryOnNotFoundGetAllBlobsStrategyTest {
|
||||||
|
|
||||||
|
Injector context;
|
||||||
|
|
||||||
|
RetryOnNotFoundGetAllBlobsStrategy<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>> map;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
void addDefaultObjectsSoThatTestsWillPass() {
|
||||||
|
context = new StubBlobStoreContextBuilder().buildInjector();
|
||||||
|
map = context
|
||||||
|
.getInstance(Key
|
||||||
|
.get(new TypeLiteral<RetryOnNotFoundGetAllBlobsStrategy<ContainerMetadata, BlobMetadata, Blob<BlobMetadata>>>() {
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void testIfNotFoundRetryOtherwiseAddToSet() throws InterruptedException,
|
||||||
|
ExecutionException, TimeoutException {
|
||||||
|
Future<Blob<BlobMetadata>> futureObject = createMock(Future.class);
|
||||||
|
Blob<BlobMetadata> object = new Blob<BlobMetadata>("key");
|
||||||
|
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andThrow(
|
||||||
|
new KeyNotFoundException());
|
||||||
|
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andReturn(
|
||||||
|
object);
|
||||||
|
replay(futureObject);
|
||||||
|
Set<Blob<BlobMetadata>> objects = new HashSet<Blob<BlobMetadata>>();
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
map.ifNotFoundRetryOtherwiseAddToSet("key", futureObject, objects);
|
||||||
|
// should have retried once
|
||||||
|
assert System.currentTimeMillis() >= time + map.requestRetryMilliseconds;
|
||||||
|
assert objects.contains(object);
|
||||||
|
assert !objects.contains(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void testIfNotFoundRetryOtherwiseAddToSetButNeverGetsIt() throws InterruptedException,
|
||||||
|
ExecutionException, TimeoutException {
|
||||||
|
Future<Blob<BlobMetadata>> futureObject = createMock(Future.class);
|
||||||
|
Blob object = createNiceMock(Blob.class);
|
||||||
|
expect(futureObject.get(map.requestTimeoutMilliseconds, TimeUnit.MILLISECONDS)).andThrow(
|
||||||
|
new KeyNotFoundException()).atLeastOnce();
|
||||||
|
replay(futureObject);
|
||||||
|
Set<Blob<BlobMetadata>> objects = new HashSet<Blob<BlobMetadata>>();
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
map.ifNotFoundRetryOtherwiseAddToSet("key", futureObject, objects);
|
||||||
|
// should have retried thrice
|
||||||
|
assert System.currentTimeMillis() >= time + map.requestRetryMilliseconds * 3;
|
||||||
|
|
||||||
|
assert !objects.contains(object);
|
||||||
|
assert !objects.contains(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue