Removed deprecated methods from the VolumeApi and updated related tests

This commit is contained in:
Jeremy Daggett 2014-07-21 08:43:15 -07:00 committed by Jeremy Daggett
parent 1223772852
commit 2db654fbe3
7 changed files with 20 additions and 248 deletions

View File

@ -48,7 +48,6 @@ import com.google.inject.Provides;
*
*/
@ConfiguresRestClient
public class NovaHttpApiModule extends HttpApiModule<NovaApi> {
public NovaHttpApiModule() {
@ -92,6 +91,8 @@ public class NovaHttpApiModule extends HttpApiModule<NovaApi> {
URI.create("http://docs.openstack.org/compute/ext/volume_types/api/v1.1"))
.put(URI.create(ExtensionNamespaces.AVAILABILITY_ZONE),
URI.create("http://docs.openstack.org/compute/ext/availabilityzone/api/v1.1"))
.put(URI.create(ExtensionNamespaces.VOLUME_ATTACHMENTS),
URI.create("http://docs.openstack.org/compute/ext/os-volume-attachment-update/api/v2"))
.build();
}

View File

@ -30,6 +30,11 @@ public final class ExtensionNamespaces {
* Volumes support
*/
public static final String VOLUMES = "http://docs.openstack.org/ext/volumes/api/v1.1";
/**
* Volume attachment support
*/
public static final String VOLUME_ATTACHMENTS = "http://docs.openstack.org/compute/ext/os-volume-attachment-update/api/v2";
/**
* Volume types support
*/

View File

@ -32,7 +32,6 @@ import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
import org.jclouds.openstack.nova.v2_0.domain.Volume;
import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
import org.jclouds.openstack.nova.v2_0.domain.VolumeSnapshot;
import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions;
import org.jclouds.openstack.nova.v2_0.options.CreateVolumeSnapshotOptions;
@ -43,7 +42,6 @@ import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
import org.jclouds.rest.annotations.WrapWith;
import com.google.common.annotations.Beta;
import com.google.common.collect.FluentIterable;
@ -118,71 +116,6 @@ public interface VolumeApi {
@Fallback(FalseOnNotFoundOr404.class)
boolean delete(@PathParam("volumeId") String volumeId);
/**
* List volume attachments for a given instance.
*
* @return all Floating IPs
* @deprecated To be removed in jclouds 1.7
* @see VolumeAttachmentApi#listAttachmentsOnServer(String)
*/
@Deprecated
@Named("volume:listAttachments")
@GET
@Path("/servers/{id}/os-volume_attachments")
@SelectJson("volumeAttachments")
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(EmptyFluentIterableOnNotFoundOr404.class)
FluentIterable<VolumeAttachment> listAttachmentsOnServer(@PathParam("id") String serverId);
/**
* Get a specific attached volume.
*
* @return data about the given volume attachment.
* @deprecated To be removed in jclouds 1.7
* @see VolumeAttachmentApi#getAttachmentForVolumeOnServer(String, String)
*/
@Deprecated
@Named("volume:getAttachments")
@GET
@Path("/servers/{serverId}/os-volume_attachments/{id}")
@SelectJson("volumeAttachment")
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@Nullable
VolumeAttachment getAttachmentForVolumeOnServer(@PathParam("id") String volumeId,
@PathParam("serverId") String serverId);
/**
* Attach a volume to an instance
*
* @return data about the new volume attachment
* @deprecated To be removed in jclouds 1.7
* @see VolumeAttachmentApi#attachVolumeToServerAsDevice(String, String, String)
*/
@Deprecated
@Named("volume:attach")
@POST
@Path("/servers/{serverId}/os-volume_attachments")
@SelectJson("volumeAttachment")
@Produces(MediaType.APPLICATION_JSON)
@WrapWith("volumeAttachment")
VolumeAttachment attachVolumeToServerAsDevice(@PayloadParam("volumeId") String volumeId,
@PathParam("serverId") String serverId, @PayloadParam("device") String device);
/**
* Detach a Volume from an instance.
*
* @return true if successful
* @deprecated To be removed in jclouds 1.7
* @see VolumeAttachmentApi#detachVolumeFromServer(String, String)
*/
@Deprecated
@Named("volume:detach")
@DELETE
@Path("/servers/{serverId}/os-volume_attachments/{id}")
@Fallback(FalseOnNotFoundOr404.class)
Boolean detachVolumeFromServer(@PathParam("id") String volumeId,
@PathParam("serverId") String serverId);
/**
* Returns a summary list of snapshots.

View File

@ -59,13 +59,13 @@ import com.google.common.collect.FluentIterable;
*
*/
@Beta
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VOLUMES)
@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VOLUME_ATTACHMENTS)
@RequestFilters(AuthenticateRequest.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/servers")
public interface VolumeAttachmentApi {
/**
* List Volume Attachments for a given Server.
* Lists Volume Attachments for a given Server.
*
* @param serverId The ID of the Server
* @return All VolumeAttachments for the Server
@ -78,7 +78,7 @@ public interface VolumeAttachmentApi {
FluentIterable<VolumeAttachment> listAttachmentsOnServer(@PathParam("serverId") String serverId);
/**
* Get a specific Volume Attachment for a Volume and Server.
* Gets a specific Volume Attachment for a Volume and Server.
*
* @param volumeId The ID of the Volume
* @param serverId The ID of the Server
@ -94,7 +94,7 @@ public interface VolumeAttachmentApi {
@PathParam("serverId") String serverId);
/**
* Attach a Volume to a Server.
* Attaches a Volume to a Server.
*
* Note: If you are using KVM as your hypervisor then the actual device name in the Server will be different than
* the one specified. When the Server sees a new device, it picks the next available name (which in most cases is
@ -115,7 +115,7 @@ public interface VolumeAttachmentApi {
@PathParam("serverId") String serverId, @PayloadParam("device") String device);
/**
* Detach a Volume from a server.
* Detaches a Volume from a server.
*
* Note: Make sure you've unmounted the volume first. Failure to do so could result in failure or data loss.
*

View File

@ -190,115 +190,6 @@ public class VolumeApiExpectTest extends BaseNovaApiExpectTest {
assertFalse(api.delete("1"));
}
public void testListAttachments() {
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/instance-1/os-volume_attachments");
VolumeApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName,
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/attachment_list.json")).build()
).getVolumeApi("az-1.region-a.geo-1").get();
Set<? extends VolumeAttachment> attachments = api.listAttachmentsOnServer("instance-1").toSet();
assertEquals(attachments, ImmutableSet.of(testAttachment()));
// double-check individual fields
VolumeAttachment attachment = Iterables.getOnlyElement(attachments);
assertEquals(attachment.getDevice(), "/dev/vdc");
assertEquals(attachment.getServerId(), "b4785058-cb80-491b-baa3-e4ee6546450e");
assertEquals(attachment.getId(), "1");
assertEquals(attachment.getVolumeId(), "1");
}
@Test(expectedExceptions = AuthorizationException.class)
public void testListAttachmentsFail() {
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/instance-2/os-volume_attachments");
VolumeApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName,
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(401).build()
).getVolumeApi("az-1.region-a.geo-1").get();
api.listAttachmentsOnServer("instance-2");
}
public void testGetAttachment() {
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/instance-1/os-volume_attachments/1");
VolumeApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName,
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/attachment_details.json")).build()
).getVolumeApi("az-1.region-a.geo-1").get();
VolumeAttachment attachment = api.getAttachmentForVolumeOnServer("1", "instance-1");
assertEquals(attachment, testAttachment());
}
public void testGetAttachmentFail() {
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/instance-1/os-volume_attachments/1");
VolumeApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName,
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
authenticatedGET().endpoint(endpoint).build(),
HttpResponse.builder().statusCode(404).build()
).getVolumeApi("az-1.region-a.geo-1").get();
assertNull(api.getAttachmentForVolumeOnServer("1", "instance-1"));
}
public void testAttachVolume() {
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/instance-1/os-volume_attachments");
VolumeApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName,
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
authenticatedGET().endpoint(endpoint).method("POST")
.payload(payloadFromStringWithContentType("{\"volumeAttachment\":{\"volumeId\":\"1\",\"device\":\"/dev/vdc\"}}", MediaType.APPLICATION_JSON)).endpoint(endpoint).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/attachment_details.json")).build()
).getVolumeApi("az-1.region-a.geo-1").get();
VolumeAttachment result = api.attachVolumeToServerAsDevice("1", "instance-1", "/dev/vdc");
assertEquals(result, testAttachment());
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testAttachVolumeFail() {
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/instance-1/os-volume_attachments");
VolumeApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName,
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
authenticatedGET().endpoint(endpoint).method("POST")
.payload(payloadFromStringWithContentType("{\"volumeAttachment\":{\"volumeId\":\"1\",\"device\":\"/dev/vdc\"}}", MediaType.APPLICATION_JSON)).endpoint(endpoint).build(),
HttpResponse.builder().statusCode(404).build()
).getVolumeApi("az-1.region-a.geo-1").get();
api.attachVolumeToServerAsDevice("1", "instance-1", "/dev/vdc");
}
public void testDetachVolume() {
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/instance-1/os-volume_attachments/1");
VolumeApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName,
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
authenticatedGET().endpoint(endpoint).method("DELETE").build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/attachment_details.json")).build()
).getVolumeApi("az-1.region-a.geo-1").get();
assertTrue(api.detachVolumeFromServer("1", "instance-1"));
}
public void testDetachVolumeFail() {
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/servers/instance-1/os-volume_attachments/1");
VolumeApi api = requestsSendResponses(
keystoneAuthWithUsernameAndPasswordAndTenantName,
responseWithKeystoneAccess, extensionsOfNovaRequest, extensionsOfNovaResponse,
authenticatedGET().endpoint(endpoint).method("DELETE").build(),
HttpResponse.builder().statusCode(404).build()
).getVolumeApi("az-1.region-a.geo-1").get();
assertFalse(api.detachVolumeFromServer("1", "instance-1"));
}
public void testListSnapshots() {
URI endpoint = URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456/os-snapshots");
VolumeApi api = requestsSendResponses(

View File

@ -24,10 +24,8 @@ import static org.testng.Assert.assertTrue;
import java.util.Set;
import org.jclouds.openstack.nova.v2_0.domain.Volume;
import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
import org.jclouds.openstack.nova.v2_0.domain.VolumeSnapshot;
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions;
import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions;
import org.jclouds.openstack.nova.v2_0.options.CreateVolumeSnapshotOptions;
import org.testng.annotations.AfterClass;
@ -215,68 +213,4 @@ public class VolumeApiLiveTest extends BaseNovaApiLiveTest {
assertEquals(a.getVolumeId(), b.getVolumeId());
}
@Test(dependsOnMethods = "testCreateVolume")
public void testAttachments() {
if (volumeOption.isPresent()) {
String server_id = null;
try {
CreateServerOptions createServerOptions = CreateServerOptions.Builder.availabilityZone(availabilityZone);
final String serverId = server_id = createServerInRegion(region, createServerOptions).getId();
Set<? extends VolumeAttachment> attachments = volumeOption.get().listAttachmentsOnServer(serverId).toSet();
assertNotNull(attachments);
final int before = attachments.size();
VolumeAttachment testAttachment = volumeOption.get().attachVolumeToServerAsDevice(testVolume.getId(),
serverId, "/dev/vdf");
assertNotNull(testAttachment.getId());
assertEquals(testAttachment.getVolumeId(), testVolume.getId());
assertTrue(retry(new Predicate<VolumeApi>() {
public boolean apply(VolumeApi volumeApi) {
return volumeOption.get().listAttachmentsOnServer(serverId).size() > before;
}
}, 60 * 1000L).apply(volumeOption.get()));
attachments = volumeOption.get().listAttachmentsOnServer(serverId).toSet();
assertNotNull(attachments);
assertEquals(attachments.size(), before + 1);
assertTrue(retry(new Predicate<VolumeApi>() {
public boolean apply(VolumeApi volumeApi) {
return volumeApi.get(testVolume.getId()).getStatus() == Volume.Status.IN_USE;
}
}, 30 * 1000L).apply(volumeOption.get()), "Volume status did not show in-use after 30 seconds");
boolean foundIt = false;
for (VolumeAttachment att : attachments) {
VolumeAttachment details = volumeOption.get()
.getAttachmentForVolumeOnServer(att.getVolumeId(), serverId);
assertNotNull(details);
assertNotNull(details.getId());
assertNotNull(details.getServerId());
assertNotNull(details.getVolumeId());
if (Objects.equal(details.getVolumeId(), testVolume.getId())) {
foundIt = true;
assertEquals(details.getDevice(), "/dev/vdf");
assertEquals(details.getServerId(), serverId);
}
}
assertTrue(foundIt, "Failed to find the attachment we created in listAttachments() response");
volumeOption.get().detachVolumeFromServer(testVolume.getId(), serverId);
assertTrue(retry(new Predicate<VolumeApi>() {
public boolean apply(VolumeApi volumeApi) {
return volumeOption.get().listAttachmentsOnServer(serverId).size() == before;
}
}, 60 * 1000L).apply(volumeOption.get()));
} finally {
if (server_id != null)
api.getServerApi(region).delete(server_id);
}
}
}
}

View File

@ -279,6 +279,14 @@
"namespace": "http://docs.openstack.org/compute/ext/availabilityzone/api/v1.1",
"alias": "os-availability-zone",
"description": "1. Add availability_zone to the Create Server v1.1 API.\n 2. Add availability zones describing.\n "
},
{
"alias": "os-volume-attachment-update",
"description": "Support for updating a volume attachment.",
"links": [],
"name": "VolumeAttachmentUpdate",
"namespace": "http://docs.openstack.org/compute/ext/os-volume-attachment-update/api/v2",
"updated": "2013-06-20T00:00:00Z"
}
]
}