From 634a33fe5fa133c95e015ceb5737d8032e7725b2 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 21 Feb 2011 20:20:37 -0800 Subject: [PATCH] added lifecycle methods to cloudstack --- .../features/VirtualMachineAsyncClient.java | 58 +++++++- .../features/VirtualMachineClient.java | 58 +++++++- .../VirtualMachineAsyncClientTest.java | 126 ++++++++++++++++-- .../VirtualMachineClientLiveTest.java | 31 ++++- 4 files changed, 255 insertions(+), 18 deletions(-) diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClient.java index b6b3b1ffae..8452b327ba 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClient.java @@ -80,8 +80,62 @@ public interface VirtualMachineAsyncClient { @Unwrap @Consumes(MediaType.APPLICATION_JSON) ListenableFuture deployVirtualMachine(@QueryParam("serviceofferingid") long serviceOfferingId, - @QueryParam("templateid") long templateId, @QueryParam("zoneid") long zoneId, - DeployVirtualMachineOptions... options); + @QueryParam("templateid") long templateId, @QueryParam("zoneid") long zoneId, + DeployVirtualMachineOptions... options); + + /** + * @see VirtualMachineClient#rebootVirtualMachine + */ + @GET + @QueryParams(keys = "command", values = "rebootVirtualMachine") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture rebootVirtualMachine(@QueryParam("id") long id); + + /** + * @see VirtualMachineClient#startVirtualMachine + */ + @GET + @QueryParams(keys = "command", values = "startVirtualMachine") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture startVirtualMachine(@QueryParam("id") long id); + + /** + * @see VirtualMachineClient#stopVirtualMachine + */ + @GET + @QueryParams(keys = "command", values = "stopVirtualMachine") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture stopVirtualMachine(@QueryParam("id") long id); + + /** + * @see VirtualMachineClient#resetPasswordForVirtualMachine + */ + @GET + @QueryParams(keys = "command", values = "resetPasswordForVirtualMachine") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture resetPasswordForVirtualMachine(@QueryParam("id") long id); + + /** + * @see VirtualMachineClient#changeServiceForVirtualMachine + */ + @GET + @QueryParams(keys = "command", values = "changeServiceForVirtualMachine") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture changeServiceForVirtualMachine(@QueryParam("id") long id); + + /** + * @see VirtualMachineClient#updateVirtualMachine + */ + @GET + @QueryParams(keys = "command", values = "updateVirtualMachine") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture updateVirtualMachine(@QueryParam("id") long id); /** * @see VirtualMachineClient#destroyVirtualMachine diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineClient.java index bde28c9f52..080a9fb4e9 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineClient.java @@ -69,7 +69,63 @@ public interface VirtualMachineClient { * @return virtual machine */ AsyncCreateResponse deployVirtualMachine(long serviceOfferingId, long templateId, long zoneId, - DeployVirtualMachineOptions... options); + DeployVirtualMachineOptions... options); + + /** + * Reboots a virtual machine. + * + * @param id + * The ID of the virtual machine + * @return job id related to destroying the VM + */ + Long rebootVirtualMachine(long id); + + /** + * Starts a virtual machine. + * + * @param id + * The ID of the virtual machine + * @return job id related to destroying the VM + */ + Long startVirtualMachine(long id); + + /** + * Stops a virtual machine. + * + * @param id + * The ID of the virtual machine + * @return job id related to destroying the VM + */ + Long stopVirtualMachine(long id); + + /** + * Resets the password for virtual machine. The virtual machine must be in a "Stopped" state and + * the template must already support this feature for this command to take effect. + * + * @param id + * The ID of the virtual machine + * @return job id related to destroying the VM + */ + Long resetPasswordForVirtualMachine(long id); + + /** + * Changes the service offering for a virtual machine. The virtual machine must be in a "Stopped" + * state for this command to take effect. + * + * @param id + * The ID of the virtual machine + * @return job id related to destroying the VM + */ + Long changeServiceForVirtualMachine(long id); + + /** + * Updates parameters of a virtual machine. + * + * @param id + * The ID of the virtual machine + * @return job id related to destroying the VM + */ + Long updateVirtualMachine(long id); /** * Destroys a virtual machine. Once destroyed, only the administrator can recover it. diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClientTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClientTest.java index a7b9ccf967..0f52c74101 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClientTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClientTest.java @@ -46,11 +46,11 @@ import com.google.inject.TypeLiteral; public class VirtualMachineAsyncClientTest extends BaseCloudStackAsyncClientTest { public void testListVirtualMachines() throws SecurityException, NoSuchMethodException, IOException { Method method = VirtualMachineAsyncClient.class.getMethod("listVirtualMachines", - ListVirtualMachinesOptions[].class); + ListVirtualMachinesOptions[].class); HttpRequest httpRequest = processor.createRequest(method); assertRequestLineEquals(httpRequest, - "GET http://localhost:8080/client/api?response=json&command=listVirtualMachines HTTP/1.1"); + "GET http://localhost:8080/client/api?response=json&command=listVirtualMachines HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertPayloadEquals(httpRequest, null, null, false); @@ -64,13 +64,13 @@ public class VirtualMachineAsyncClientTest extends BaseCloudStackAsyncClientTest public void testListVirtualMachinesOptions() throws SecurityException, NoSuchMethodException, IOException { Method method = VirtualMachineAsyncClient.class.getMethod("listVirtualMachines", - ListVirtualMachinesOptions[].class); - HttpRequest httpRequest = processor.createRequest(method, - ListVirtualMachinesOptions.Builder.accountInDomain("adrian", 6).usesVirtualNetwork(true)); + ListVirtualMachinesOptions[].class); + HttpRequest httpRequest = processor.createRequest(method, ListVirtualMachinesOptions.Builder.accountInDomain( + "adrian", 6).usesVirtualNetwork(true)); assertRequestLineEquals( - httpRequest, - "GET http://localhost:8080/client/api?response=json&command=listVirtualMachines&account=adrian&domainid=6&forvirtualnetwork=true HTTP/1.1"); + httpRequest, + "GET http://localhost:8080/client/api?response=json&command=listVirtualMachines&account=adrian&domainid=6&forvirtualnetwork=true HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertPayloadEquals(httpRequest, null, null, false); @@ -87,7 +87,7 @@ public class VirtualMachineAsyncClientTest extends BaseCloudStackAsyncClientTest HttpRequest httpRequest = processor.createRequest(method, 5); assertRequestLineEquals(httpRequest, - "GET http://localhost:8080/client/api?response=json&command=listVirtualMachines&id=5 HTTP/1.1"); + "GET http://localhost:8080/client/api?response=json&command=listVirtualMachines&id=5 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertPayloadEquals(httpRequest, null, null, false); @@ -101,12 +101,12 @@ public class VirtualMachineAsyncClientTest extends BaseCloudStackAsyncClientTest public void testDeployVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { Method method = VirtualMachineAsyncClient.class.getMethod("deployVirtualMachine", long.class, long.class, - long.class, DeployVirtualMachineOptions[].class); + long.class, DeployVirtualMachineOptions[].class); HttpRequest httpRequest = processor.createRequest(method, 4, 5, 6); assertRequestLineEquals( - httpRequest, - "GET http://localhost:8080/client/api?response=json&command=deployVirtualMachine&serviceofferingid=4&zoneid=6&templateid=5 HTTP/1.1"); + httpRequest, + "GET http://localhost:8080/client/api?response=json&command=deployVirtualMachine&serviceofferingid=4&zoneid=6&templateid=5 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertPayloadEquals(httpRequest, null, null, false); @@ -118,12 +118,114 @@ public class VirtualMachineAsyncClientTest extends BaseCloudStackAsyncClientTest } + public void testRebootVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { + Method method = VirtualMachineAsyncClient.class.getMethod("rebootVirtualMachine", long.class); + HttpRequest httpRequest = processor.createRequest(method, 5); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=rebootVirtualMachine&id=5 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(httpRequest); + + } + + public void testStartVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { + Method method = VirtualMachineAsyncClient.class.getMethod("startVirtualMachine", long.class); + HttpRequest httpRequest = processor.createRequest(method, 5); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=startVirtualMachine&id=5 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(httpRequest); + + } + + public void testStopVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { + Method method = VirtualMachineAsyncClient.class.getMethod("stopVirtualMachine", long.class); + HttpRequest httpRequest = processor.createRequest(method, 5); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=stopVirtualMachine&id=5 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(httpRequest); + + } + + public void testResetPasswordForVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { + Method method = VirtualMachineAsyncClient.class.getMethod("resetPasswordForVirtualMachine", long.class); + HttpRequest httpRequest = processor.createRequest(method, 5); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=resetPasswordForVirtualMachine&id=5 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(httpRequest); + + } + + public void testChangeServiceForVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { + Method method = VirtualMachineAsyncClient.class.getMethod("changeServiceForVirtualMachine", long.class); + HttpRequest httpRequest = processor.createRequest(method, 5); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=changeServiceForVirtualMachine&id=5 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(httpRequest); + + } + + public void testUpdateVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { + Method method = VirtualMachineAsyncClient.class.getMethod("updateVirtualMachine", long.class); + HttpRequest httpRequest = processor.createRequest(method, 5); + + assertRequestLineEquals(httpRequest, + "GET http://localhost:8080/client/api?response=json&command=updateVirtualMachine&id=5 HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyNestedJsonValue.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(httpRequest); + + } + public void testDestroyVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { Method method = VirtualMachineAsyncClient.class.getMethod("destroyVirtualMachine", long.class); HttpRequest httpRequest = processor.createRequest(method, 5); assertRequestLineEquals(httpRequest, - "GET http://localhost:8080/client/api?response=json&command=destroyVirtualMachine&id=5 HTTP/1.1"); + "GET http://localhost:8080/client/api?response=json&command=destroyVirtualMachine&id=5 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertPayloadEquals(httpRequest, null, null, false); diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java index cafd513dc3..50b501ee06 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java @@ -45,6 +45,7 @@ import org.testng.annotations.AfterGroups; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import static com.google.common.base.Predicates.*; import com.google.common.collect.ComparisonChain; import com.google.common.collect.Ordering; @@ -74,7 +75,8 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { @Override public boolean apply(Template arg0) { - return arg0.getZoneId() == zone.getId() && arg0.isFeatured() && arg0.isReady(); + return arg0.getZoneId() == zone.getId() && arg0.isFeatured() && arg0.isReady() + && arg0.getOSType().equals("Ubuntu 10.04 (64-bit)"); } }).getId(); @@ -115,12 +117,35 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { return vm; } - public void testCreateDestroyVirtualMachine() throws Exception { + public void testCreateVirtualMachine() throws Exception { vm = createVirtualMachine(client, jobComplete, virtualMachineRunning); - assertEquals(vm.getRootDeviceType(), "NetworkFilesystem"); + assert or(equalTo("NetworkFilesystem"), equalTo("IscsiLUN")).apply(vm.getRootDeviceType()) : vm; checkVm(vm); } + @Test(dependsOnMethods = "testCreateVirtualMachine") + public void testLifeCycle() throws Exception { + Long job = client.getVirtualMachineClient().stopVirtualMachine(vm.getId()); + assert jobComplete.apply(job); + vm = client.getVirtualMachineClient().getVirtualMachine(vm.getId()); + assertEquals(vm.getState(), VirtualMachine.State.STOPPED); + + job = client.getVirtualMachineClient().resetPasswordForVirtualMachine(vm.getId()); + assert jobComplete.apply(job); + vm = client.getVirtualMachineClient().getVirtualMachine(vm.getId()); + // TODO: check if error or not base on isPasswordEnabled + + job = client.getVirtualMachineClient().startVirtualMachine(vm.getId()); + assert jobComplete.apply(job); + vm = client.getVirtualMachineClient().getVirtualMachine(vm.getId()); + assertEquals(vm.getState(), VirtualMachine.State.RUNNING); + + job = client.getVirtualMachineClient().rebootVirtualMachine(vm.getId()); + assert jobComplete.apply(job); + vm = client.getVirtualMachineClient().getVirtualMachine(vm.getId()); + assertEquals(vm.getState(), VirtualMachine.State.RUNNING); + } + @AfterGroups(groups = "live") protected void tearDown() { if (vm != null) {