removed redundant retrying assertion code

This commit is contained in:
Adrian Cole 2013-01-12 14:04:47 -08:00
parent cca73d8a69
commit 015fbf22a2
6 changed files with 70 additions and 132 deletions

View File

@ -17,6 +17,7 @@
* under the License.
*/
package org.jclouds.atmos.util;
import static com.google.common.base.Preconditions.checkState;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
@ -31,6 +32,7 @@ import org.jclouds.atmos.domain.AtmosObject;
import org.jclouds.atmos.filters.SignRequest;
import org.jclouds.atmos.options.PutOptions;
import org.jclouds.atmos.xml.ErrorHandler;
import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.blobstore.KeyAlreadyExistsException;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.crypto.Crypto;
@ -38,9 +40,9 @@ import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpException;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.util.Assertions;
import org.jclouds.predicates.RetryablePredicate;
import com.google.common.base.Supplier;
import com.google.common.base.Predicate;
/**
* Encryption, Hashing, and IO Utilities needed to sign and verify Atmos Storage requests and
@ -78,25 +80,23 @@ public class AtmosUtils {
sync.createFile(container, object, options);
} catch(KeyAlreadyExistsException e) {
deleteAndEnsureGone(sync, path);
deletePathAndEnsureGone(sync, path);
sync.createFile(container, object, options);
}
return path;
}
public static void deleteAndEnsureGone(final AtmosClient sync, final String path) {
public static void deletePathAndEnsureGone(final AtmosClient sync, String path) {
checkState(new RetryablePredicate<String>(new Predicate<String>() {
public boolean apply(String in) {
try {
if (!Assertions.eventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
sync.deletePath(path);
return !sync.pathExists(path);
sync.deletePath(in);
return !sync.pathExists(in);
} catch (ContainerNotFoundException e) {
return true;
}
}, 3000)) {
throw new IllegalStateException(path + " still exists after deleting!");
}
} catch (InterruptedException e) {
throw new IllegalStateException(path + " interrupted during deletion!", e);
}
}, 3000).apply(path), "%s still exists after deleting!", path);
}
public AtmosError parseAtmosErrorFromContent(HttpCommand command, HttpResponse response, String content)

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.atmos;
import static com.google.common.base.Preconditions.checkState;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
@ -34,17 +35,18 @@ import org.jclouds.atmos.domain.DirectoryEntry;
import org.jclouds.atmos.domain.FileType;
import org.jclouds.atmos.domain.SystemMetadata;
import org.jclouds.atmos.options.ListOptions;
import org.jclouds.blobstore.ContainerNotFoundException;
import org.jclouds.blobstore.KeyAlreadyExistsException;
import org.jclouds.blobstore.KeyNotFoundException;
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
import org.jclouds.http.HttpResponseException;
import org.jclouds.io.Payloads;
import org.jclouds.io.payloads.InputStreamPayload;
import org.jclouds.util.Assertions;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
@ -320,17 +322,21 @@ public class AtmosClientLiveTest extends BaseBlobStoreIntegrationTest {
}
protected void deleteConsistencyAware(final String path) throws InterruptedException, ExecutionException,
protected void deleteConsistencyAware(String path) throws InterruptedException, ExecutionException,
TimeoutException {
try {
getApi().deletePath(path);
} catch (KeyNotFoundException ex) {
}
assert Assertions.eventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
return !getApi().pathExists(path);
checkState(new RetryablePredicate<String>(new Predicate<String>() {
public boolean apply(String in) {
try {
return !getApi().pathExists(in);
} catch (ContainerNotFoundException e) {
return true;
}
}, INCONSISTENCY_WINDOW);
}
}, INCONSISTENCY_WINDOW).apply(path), "%s still exists after deleting!", path);
}
protected void retryAndCheckSystemMetadataAndPutIfPresentReplaceStrategy(AtmosObject object) throws Exception {

View File

@ -19,6 +19,7 @@
package org.jclouds.s3.blobstore;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.Set;
@ -42,6 +43,7 @@ import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.http.options.GetOptions;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.s3.S3Client;
import org.jclouds.s3.blobstore.functions.BlobToObject;
import org.jclouds.s3.blobstore.functions.BucketToResourceList;
@ -57,9 +59,9 @@ import org.jclouds.s3.options.ListBucketOptions;
import org.jclouds.s3.options.PutBucketOptions;
import org.jclouds.s3.options.PutObjectOptions;
import org.jclouds.s3.util.S3Utils;
import org.jclouds.util.Assertions;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
@ -148,38 +150,20 @@ public class S3BlobStore extends BaseBlobStore {
}
/**
* This implementation invokes {@link #deleteAndEnsurePathGone}
*
* @param container
* bucket name
* This implementation invokes {@link #clearContainer} then {@link S3Client#deleteBucketIfEmpty} until it is true.
*/
@Override
public void deleteContainer(String container) {
clearAndDeleteContainer(container);
}
/**
* This implementation invokes {@link #clearContainer} then {@link S3Client#deleteBucketIfEmpty}
* until it is true.
*/
public void clearAndDeleteContainer(final String container) {
protected void deletePathAndEnsureGone(String path) {
checkState(new RetryablePredicate<String>(new Predicate<String>() {
public boolean apply(String in) {
try {
//TODO: probably it is better to use a retryable predicate
if (!Assertions.eventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
try {
clearContainer(container);
return sync.deleteBucketIfEmpty(container);
clearContainer(in);
return sync.deleteBucketIfEmpty(in);
} catch (ContainerNotFoundException e) {
return true;
}
}
}, 30000)) {
throw new IllegalStateException(container + " still exists after deleting!");
}
} catch (InterruptedException e) {
throw new IllegalStateException(container + " interrupted during deletion!", e);
}
}, 30000).apply(path), "%s still exists after deleting!", path);
}
/**

View File

@ -19,6 +19,7 @@
package org.jclouds.blobstore.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import java.util.Set;
@ -38,10 +39,12 @@ import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.blobstore.util.internal.BlobUtilsImpl;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.util.Assertions;
import org.jclouds.predicates.RetryablePredicate;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@ -254,7 +257,7 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore {
return org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable<Void>() {
public Void call() throws Exception {
deleteAndEnsurePathGone(container);
deletePathAndEnsureGone(container);
return null;
}
@ -265,24 +268,17 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore {
}), service);
}
protected void deleteAndEnsurePathGone(final String container) {
protected void deletePathAndEnsureGone(String path) {
checkState(new RetryablePredicate<String>(new Predicate<String>() {
public boolean apply(String in) {
try {
if (!Assertions.eventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
try {
clearContainer(container, recursive());
return deleteAndVerifyContainerGone(container);
clearContainer(in, recursive());
return deleteAndVerifyContainerGone(in);
} catch (ContainerNotFoundException e) {
return true;
}
}
}, 30000)) {
throw new IllegalStateException(container + " still exists after deleting!");
}
} catch (InterruptedException e) {
throw new IllegalStateException(container + " interrupted during deletion!", e);
}
}, 30000).apply(path), "%s still exists after deleting!", path);
}
@Override

View File

@ -19,6 +19,7 @@
package org.jclouds.blobstore.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.blobstore.options.ListContainerOptions.Builder.recursive;
import java.util.Set;
@ -34,10 +35,12 @@ import org.jclouds.blobstore.domain.PageSet;
import org.jclouds.blobstore.domain.StorageMetadata;
import org.jclouds.blobstore.options.ListContainerOptions;
import org.jclouds.blobstore.util.BlobUtils;
import org.jclouds.blobstore.util.internal.BlobUtilsImpl;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.util.Assertions;
import org.jclouds.predicates.RetryablePredicate;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
/**
@ -189,28 +192,21 @@ public abstract class BaseBlobStore implements BlobStore {
* bucket name
*/
@Override
public void deleteContainer(final String container) {
clearAndDeleteContainer(container);
public void deleteContainer(String container) {
deletePathAndEnsureGone(container);
}
protected void clearAndDeleteContainer(final String container) {
protected void deletePathAndEnsureGone(String path) {
checkState(new RetryablePredicate<String>(new Predicate<String>() {
public boolean apply(String in) {
try {
if (!Assertions.eventuallyTrue(new Supplier<Boolean>() {
public Boolean get() {
try {
clearContainer(container, recursive());
return deleteAndVerifyContainerGone(container);
clearContainer(in, recursive());
return deleteAndVerifyContainerGone(in);
} catch (ContainerNotFoundException e) {
return true;
}
}
}, 30000)) {
throw new IllegalStateException(container + " still exists after deleting!");
}
} catch (InterruptedException e) {
throw new IllegalStateException(container + " interrupted during deletion!", e);
}
}, 30000).apply(path), "%s still exists after deleting!", path);
}
@Override

View File

@ -1,44 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.util;
import com.google.common.base.Supplier;
/**
*
* @author Adrian Cole
*/
public class Assertions {
public static boolean eventuallyTrue(Supplier<Boolean> assertion, long inconsistencyMillis)
throws InterruptedException {
for (int i = 0; i < 30; i++) {
if (!assertion.get()) {
Thread.sleep(inconsistencyMillis / 30);
continue;
}
return true;
}
return false;
}
}