mirror of https://github.com/apache/jclouds.git
Issue 695: Methods to powerOn/powerOff/shutdown/reboot a VM
This commit is contained in:
parent
835ea8bb57
commit
8a3c919009
|
@ -22,6 +22,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import org.jclouds.http.filters.BasicAuthentication;
|
import org.jclouds.http.filters.BasicAuthentication;
|
||||||
import org.jclouds.rest.annotations.*;
|
import org.jclouds.rest.annotations.*;
|
||||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
import org.jclouds.tmrk.enterprisecloud.domain.Task;
|
||||||
import org.jclouds.tmrk.enterprisecloud.domain.hardware.HardwareConfiguration;
|
import org.jclouds.tmrk.enterprisecloud.domain.hardware.HardwareConfiguration;
|
||||||
import org.jclouds.tmrk.enterprisecloud.domain.network.AssignedIpAddresses;
|
import org.jclouds.tmrk.enterprisecloud.domain.network.AssignedIpAddresses;
|
||||||
import org.jclouds.tmrk.enterprisecloud.domain.vm.VirtualMachine;
|
import org.jclouds.tmrk.enterprisecloud.domain.vm.VirtualMachine;
|
||||||
|
@ -31,6 +32,8 @@ import org.jclouds.tmrk.enterprisecloud.functions.ReturnEmptyVirtualMachinesOnNo
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,4 +94,44 @@ public interface VirtualMachineAsyncClient {
|
||||||
@JAXBResponseParser
|
@JAXBResponseParser
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
ListenableFuture<HardwareConfiguration> getHardwareConfiguration(@EndpointParam URI uri);
|
ListenableFuture<HardwareConfiguration> getHardwareConfiguration(@EndpointParam URI uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VirtualMachineClient#powerOn
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/action/powerOn")
|
||||||
|
@Consumes("application/vnd.tmrk.cloud.task")
|
||||||
|
@JAXBResponseParser
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Task> powerOn(@EndpointParam URI uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VirtualMachineClient#powerOff
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/action/powerOff")
|
||||||
|
@Consumes("application/vnd.tmrk.cloud.task")
|
||||||
|
@JAXBResponseParser
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Task> powerOff(@EndpointParam URI uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VirtualMachineClient#reboot
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/action/reboot")
|
||||||
|
@Consumes("application/vnd.tmrk.cloud.task")
|
||||||
|
@JAXBResponseParser
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Task> reboot(@EndpointParam URI uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see VirtualMachineClient#shutdown
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/action/shutdown")
|
||||||
|
@Consumes("application/vnd.tmrk.cloud.task")
|
||||||
|
@JAXBResponseParser
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Task> shutdown(@EndpointParam URI uri);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.jclouds.tmrk.enterprisecloud.features;
|
package org.jclouds.tmrk.enterprisecloud.features;
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.tmrk.enterprisecloud.domain.Task;
|
||||||
import org.jclouds.tmrk.enterprisecloud.domain.hardware.HardwareConfiguration;
|
import org.jclouds.tmrk.enterprisecloud.domain.hardware.HardwareConfiguration;
|
||||||
import org.jclouds.tmrk.enterprisecloud.domain.network.AssignedIpAddresses;
|
import org.jclouds.tmrk.enterprisecloud.domain.network.AssignedIpAddresses;
|
||||||
import org.jclouds.tmrk.enterprisecloud.domain.vm.VirtualMachine;
|
import org.jclouds.tmrk.enterprisecloud.domain.vm.VirtualMachine;
|
||||||
|
@ -80,4 +81,44 @@ public interface VirtualMachineClient {
|
||||||
*/
|
*/
|
||||||
HardwareConfiguration getHardwareConfiguration(URI uri);
|
HardwareConfiguration getHardwareConfiguration(URI uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Action Virtual Machines Power On call powers on a specified virtual machine.
|
||||||
|
* If successful, the call returns the task that powered on the virtual machine.
|
||||||
|
* Note: To power on requires a <PoweredOn> value of false.
|
||||||
|
* @param uri the uri of the virtual machine
|
||||||
|
* @return Task
|
||||||
|
*/
|
||||||
|
Task powerOn(URI uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Action Virtual Machines Power Off call powers off a specified virtual machine.
|
||||||
|
* Power off simply terminates the virtual machine whereas
|
||||||
|
* shutdown requests the virtual machine to end all processes and turn itself off
|
||||||
|
* when all processes complete.
|
||||||
|
* If successful, the call returns the task that powered off the virtual machine.
|
||||||
|
* Note: To power off requires a <PoweredOn> value of true.
|
||||||
|
* @param uri the uri of the virtual machine
|
||||||
|
* @return Task
|
||||||
|
*/
|
||||||
|
Task powerOff(URI uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Action Virtual Machines Power Reboot call reboots a specified virtual machine.
|
||||||
|
* If successful, the call returns the task that rebooted the virtual machine.
|
||||||
|
* Note: To reboot requires a <ToolsStatus> value of Current or OutOfDate and a <PoweredOn> value of true.
|
||||||
|
* @param uri the uri of the virtual machine
|
||||||
|
* @return Task
|
||||||
|
*/
|
||||||
|
Task reboot(URI uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Action Virtual Machines Power Shutdown call shuts down a specified virtual machine.
|
||||||
|
* Shutdown requests the virtual machine to end all processes and turn itself off when all processes complete whereas power off simply terminates the virtual machine.
|
||||||
|
* If successful, the call returns the task that shut down the virtual machine.
|
||||||
|
* Note: To shutdown requires a <ToolsStatus> value of Current or OutOfDate and a <PoweredOn> value of true.
|
||||||
|
* @param uri the uri of the virtual machine
|
||||||
|
* @return Task
|
||||||
|
*/
|
||||||
|
Task shutdown(URI uri);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests annotation parsing of {@code TaskAsyncClient}
|
* Tests annotation parsing of {@code VirtualMachineAsyncClient}
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -109,6 +109,62 @@ public class VirtualMachineAsyncClientTest extends BaseTerremarkEnterpriseCloudA
|
||||||
checkFilters(httpRequest);
|
checkFilters(httpRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPowerOn() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException {
|
||||||
|
Method method = VirtualMachineAsyncClient.class.getMethod("powerOn", URI.class);
|
||||||
|
HttpRequest httpRequest = processor.createRequest(method,new URI("/cloudapi/ecloud/virtualmachines/5504"));
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpRequest, "POST https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/virtualmachines/5504/action/powerOn HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/vnd.tmrk.cloud.task\nx-tmrk-version: 2011-07-01\n");
|
||||||
|
assertPayloadEquals(httpRequest, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(httpRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPowerOff() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException {
|
||||||
|
Method method = VirtualMachineAsyncClient.class.getMethod("powerOff", URI.class);
|
||||||
|
HttpRequest httpRequest = processor.createRequest(method,new URI("/cloudapi/ecloud/virtualmachines/5504"));
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpRequest, "POST https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/virtualmachines/5504/action/powerOff HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/vnd.tmrk.cloud.task\nx-tmrk-version: 2011-07-01\n");
|
||||||
|
assertPayloadEquals(httpRequest, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(httpRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testReboot() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException {
|
||||||
|
Method method = VirtualMachineAsyncClient.class.getMethod("reboot", URI.class);
|
||||||
|
HttpRequest httpRequest = processor.createRequest(method,new URI("/cloudapi/ecloud/virtualmachines/5504"));
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpRequest, "POST https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/virtualmachines/5504/action/reboot HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/vnd.tmrk.cloud.task\nx-tmrk-version: 2011-07-01\n");
|
||||||
|
assertPayloadEquals(httpRequest, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(httpRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testShutdown() throws SecurityException, NoSuchMethodException, IOException, URISyntaxException {
|
||||||
|
Method method = VirtualMachineAsyncClient.class.getMethod("shutdown", URI.class);
|
||||||
|
HttpRequest httpRequest = processor.createRequest(method,new URI("/cloudapi/ecloud/virtualmachines/5504"));
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpRequest, "POST https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/virtualmachines/5504/action/shutdown HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/vnd.tmrk.cloud.task\nx-tmrk-version: 2011-07-01\n");
|
||||||
|
assertPayloadEquals(httpRequest, null, null, false);
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class);
|
||||||
|
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
|
||||||
|
|
||||||
|
checkFilters(httpRequest);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TypeLiteral<RestAnnotationProcessor<VirtualMachineAsyncClient>> createTypeLiteral() {
|
protected TypeLiteral<RestAnnotationProcessor<VirtualMachineAsyncClient>> createTypeLiteral() {
|
||||||
return new TypeLiteral<RestAnnotationProcessor<VirtualMachineAsyncClient>>() {
|
return new TypeLiteral<RestAnnotationProcessor<VirtualMachineAsyncClient>>() {
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/**
|
||||||
|
* 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.tmrk.enterprisecloud.features;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
import org.jclouds.tmrk.enterprisecloud.domain.Task;
|
||||||
|
import org.jclouds.tmrk.enterprisecloud.domain.vm.VirtualMachine;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code VirtualMachineClient} actions
|
||||||
|
* @author Jason King
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "VirtualMachineClientActionsLiveTest")
|
||||||
|
public class VirtualMachineClientActionsLiveTest extends BaseTerremarkEnterpriseCloudClientLiveTest {
|
||||||
|
@BeforeGroups(groups = { "live" })
|
||||||
|
public void setupClient() {
|
||||||
|
super.setupClient();
|
||||||
|
client = context.getApi().getVirtualMachineClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: Need a create call to make this not dependent on existing vm
|
||||||
|
private static final String vmURI = "/cloudapi/ecloud/virtualmachines/5504";
|
||||||
|
|
||||||
|
private VirtualMachineClient client;
|
||||||
|
private VirtualMachine vm;
|
||||||
|
|
||||||
|
public void testPowerOn() throws Exception {
|
||||||
|
vm = client.getVirtualMachine(new URI(vmURI));
|
||||||
|
assertFalse(vm.isPoweredOn());
|
||||||
|
Task task = client.powerOn(vm.getHref());
|
||||||
|
RetryablePredicate retryablePredicate = new RetryablePredicate(taskFinished(), 1000*60);
|
||||||
|
if (!retryablePredicate.apply(task)) {
|
||||||
|
fail("Did not manage to powerOn VM within timeout");
|
||||||
|
}
|
||||||
|
|
||||||
|
vm = client.getVirtualMachine(vm.getHref());
|
||||||
|
assertTrue(vm.isPoweredOn());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testPowerOn")
|
||||||
|
public void testShutdown() {
|
||||||
|
//System.out.println("shutdown");
|
||||||
|
//Needs tool status Current/OutOfDate
|
||||||
|
//check state
|
||||||
|
//shutdown
|
||||||
|
//wait until done
|
||||||
|
//power on
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testShutdown")
|
||||||
|
public void testReboot() {
|
||||||
|
//System.out.println("reboot");
|
||||||
|
//Needs tool status Current/OutOfDate
|
||||||
|
//check state
|
||||||
|
//reboot
|
||||||
|
//wait until done
|
||||||
|
}
|
||||||
|
|
||||||
|
//@Test(dependsOnMethods = "testReboot")
|
||||||
|
@Test(dependsOnMethods = "testPowerOn")
|
||||||
|
public void testPowerOff() {
|
||||||
|
Task task = client.powerOff(vm.getHref());
|
||||||
|
RetryablePredicate retryablePredicate = new RetryablePredicate(taskFinished(), 1000*60);
|
||||||
|
if (!retryablePredicate.apply(task)) {
|
||||||
|
fail("Did not manage to powerOff VM within timeout");
|
||||||
|
}
|
||||||
|
|
||||||
|
vm = client.getVirtualMachine(vm.getHref());
|
||||||
|
assertFalse(vm.isPoweredOn());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probably generally useful
|
||||||
|
private Predicate taskFinished() {
|
||||||
|
return new Predicate<Task>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(@Nullable Task task) {
|
||||||
|
TaskClient taskClient = context.getApi().getTaskClient();
|
||||||
|
task = taskClient.getTask(task.getHref());
|
||||||
|
Task.Status status = task.getStatus();
|
||||||
|
switch(status) {
|
||||||
|
case QUEUED:
|
||||||
|
case RUNNING:
|
||||||
|
return false;
|
||||||
|
case COMPLETE:
|
||||||
|
case SUCCESS:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Task Failed:"+task.getHref()+", Status:"+status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue