Added awaitDeleted() to VolumePredicates and SnapshotPredicates. Improved Volume.forId().

This commit is contained in:
Everett Toews 2012-11-13 17:54:10 -06:00
parent b49484be05
commit db4c5fc0f9
6 changed files with 91 additions and 17 deletions

View File

@ -206,8 +206,16 @@ public class Volume {
} }
} }
/**
* Creates a dummy Volume when you need a Volume with just the volumeId.
* Several fields must be set in the returned Volume:
*
* 1. status=Status.UNRECOGNIZED
* 2. zone="nova"
* 3. created=[The Date the method was called]
*/
public static Volume forId(String volumeId) { public static Volume forId(String volumeId) {
return builder().id(volumeId).build(); return builder().id(volumeId).status(Status.UNRECOGNIZED).zone("nova").created(new Date()).build();
} }
private final String id; private final String id;

View File

@ -74,6 +74,19 @@ public class SnapshotPredicates {
return new RetryablePredicate<Snapshot>(statusPredicate, 1200, 5, 5, TimeUnit.SECONDS); return new RetryablePredicate<Snapshot>(statusPredicate, 1200, 5, 5, TimeUnit.SECONDS);
} }
/**
* Wait until a Snapshot no longer exists.
*
* @param snapshotApi The SnapshotApi in the zone where your Snapshot resides.
* @return RetryablePredicate That will check the whether the Snapshot exists
* every 5 seconds for a maxiumum of 20 minutes.
*/
public static RetryablePredicate<Snapshot> awaitDeleted(SnapshotApi snapshotApi) {
DeletedPredicate deletedPredicate = new DeletedPredicate(snapshotApi);
return new RetryablePredicate<Snapshot>(deletedPredicate, 1200, 5, 5, TimeUnit.SECONDS);
}
public static RetryablePredicate<Snapshot> awaitStatus( public static RetryablePredicate<Snapshot> awaitStatus(
SnapshotApi snapshotApi, Volume.Status status, long maxWaitInSec, long periodInSec) { SnapshotApi snapshotApi, Volume.Status status, long maxWaitInSec, long periodInSec) {
StatusUpdatedPredicate statusPredicate = new StatusUpdatedPredicate(snapshotApi, status); StatusUpdatedPredicate statusPredicate = new StatusUpdatedPredicate(snapshotApi, status);
@ -95,7 +108,7 @@ public class SnapshotPredicates {
*/ */
@Override @Override
public boolean apply(Snapshot snapshot) { public boolean apply(Snapshot snapshot) {
checkNotNull(snapshot, "snapshotId must be defined"); checkNotNull(snapshot, "snapshot must be defined");
if (status.equals(snapshot.getStatus())) { if (status.equals(snapshot.getStatus())) {
return true; return true;
@ -108,4 +121,22 @@ public class SnapshotPredicates {
} }
} }
} }
private static class DeletedPredicate implements Predicate<Snapshot> {
private SnapshotApi snapshotApi;
public DeletedPredicate(SnapshotApi snapshotApi) {
this.snapshotApi = checkNotNull(snapshotApi, "snapshotApi must be defined");
}
/**
* @return boolean Return true when the snapshot is deleted, false otherwise
*/
@Override
public boolean apply(Snapshot snapshot) {
checkNotNull(snapshot, "snapshot must be defined");
return snapshotApi.get(snapshot.getId()) == null;
}
}
} }

View File

@ -85,6 +85,19 @@ public class VolumePredicates {
return new RetryablePredicate<Volume>(statusPredicate, 600, 5, 5, TimeUnit.SECONDS); return new RetryablePredicate<Volume>(statusPredicate, 600, 5, 5, TimeUnit.SECONDS);
} }
/**
* Wait until a Volume no longer exists.
*
* @param volumeApi The VolumeApi in the zone where your Volume resides.
* @return RetryablePredicate That will check the whether the Volume exists
* every 5 seconds for a maxiumum of 10 minutes.
*/
public static RetryablePredicate<Volume> awaitDeleted(VolumeApi volumeApi) {
DeletedPredicate deletedPredicate = new DeletedPredicate(volumeApi);
return new RetryablePredicate<Volume>(deletedPredicate, 600, 5, 5, TimeUnit.SECONDS);
}
public static RetryablePredicate<Volume> awaitStatus( public static RetryablePredicate<Volume> awaitStatus(
VolumeApi volumeApi, Volume.Status status, long maxWaitInSec, long periodInSec) { VolumeApi volumeApi, Volume.Status status, long maxWaitInSec, long periodInSec) {
@ -120,4 +133,22 @@ public class VolumePredicates {
} }
} }
} }
private static class DeletedPredicate implements Predicate<Volume> {
private VolumeApi volumeApi;
public DeletedPredicate(VolumeApi volumeApi) {
this.volumeApi = checkNotNull(volumeApi, "volumeApi must be defined");
}
/**
* @return boolean Return true when the snapshot is deleted, false otherwise
*/
@Override
public boolean apply(Volume volume) {
checkNotNull(volume, "volume must be defined");
return volumeApi.get(volume.getId()) == null;
}
}
} }

View File

@ -0,0 +1,16 @@
package org.jclouds.openstack.cinder.v1.domain;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
@Test(groups = "unit", testName = "VolumeTest")
public class VolumeTest {
public void testVolumeForId() {
Volume volume = Volume.forId("60761c60-0f56-4499-b522-ff13e120af10");
assertEquals(volume.getId(), "60761c60-0f56-4499-b522-ff13e120af10");
assertEquals(volume.getStatus(), Volume.Status.UNRECOGNIZED);
assertEquals(volume.getZone(), "nova");
}
}

View File

@ -31,13 +31,11 @@ import org.jclouds.openstack.cinder.v1.options.CreateSnapshotOptions;
import org.jclouds.openstack.cinder.v1.options.CreateVolumeOptions; import org.jclouds.openstack.cinder.v1.options.CreateVolumeOptions;
import org.jclouds.openstack.cinder.v1.predicates.SnapshotPredicates; import org.jclouds.openstack.cinder.v1.predicates.SnapshotPredicates;
import org.jclouds.openstack.cinder.v1.predicates.VolumePredicates; import org.jclouds.openstack.cinder.v1.predicates.VolumePredicates;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterClass; import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
/** /**
@ -71,22 +69,12 @@ public class VolumeAndSnapshotApiLiveTest extends BaseCinderApiLiveTest {
protected void tearDownContext() { protected void tearDownContext() {
if (testSnapshot != null) { if (testSnapshot != null) {
assertTrue(snapshotApi.delete(testSnapshot.getId())); assertTrue(snapshotApi.delete(testSnapshot.getId()));
assertTrue(new RetryablePredicate<SnapshotApi>(new Predicate<SnapshotApi>() { assertTrue(SnapshotPredicates.awaitDeleted(snapshotApi).apply(testSnapshot));
@Override
public boolean apply(SnapshotApi snapshotApi) {
return snapshotApi.get(testSnapshot.getId()) == null;
}
}, 300 * 1000L).apply(snapshotApi));
} }
if (testVolume != null) { if (testVolume != null) {
assertTrue(volumeApi.delete(testVolume.getId())); assertTrue(volumeApi.delete(testVolume.getId()));
assertTrue(new RetryablePredicate<VolumeApi>(new Predicate<VolumeApi>() { assertTrue(VolumePredicates.awaitDeleted(volumeApi).apply(testVolume));
@Override
public boolean apply(VolumeApi volumeApi) {
return volumeApi.get(testVolume.getId()) == null;
}
}, 300 * 1000L).apply(volumeApi));
} }
super.tearDownContext(); super.tearDownContext();

View File

@ -195,7 +195,7 @@ public class VolumeApiExpectTest extends BaseCinderApiExpectTest {
assertFalse(api.delete("60761c60-0f56-4499-b522-ff13e120af10")); assertFalse(api.delete("60761c60-0f56-4499-b522-ff13e120af10"));
} }
protected Volume testVolumeCreate() { protected Volume testVolumeCreate() {
return Volume.builder() return Volume.builder()
.id("60761c60-0f56-4499-b522-ff13e120af10") .id("60761c60-0f56-4499-b522-ff13e120af10")