Merge pull request #488 from aledsage/issue-830-vdc-admin-strike2

Issue #830 vcloud-director: vdc admin client
This commit is contained in:
Adrian Cole 2012-03-20 12:11:15 -07:00
commit ee2a7e96ba
6 changed files with 281 additions and 37 deletions

View File

@ -21,13 +21,22 @@ package org.jclouds.vcloud.director.v1_5.features;
import java.net.URI; import java.net.URI;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.JAXBResponseParser; import org.jclouds.rest.annotations.JAXBResponseParser;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
import org.jclouds.vcloud.director.v1_5.domain.AdminVdc; import org.jclouds.vcloud.director.v1_5.domain.AdminVdc;
import org.jclouds.vcloud.director.v1_5.domain.Task;
import org.jclouds.vcloud.director.v1_5.features.MetadataAsyncClient.Writable;
import org.jclouds.vcloud.director.v1_5.filters.AddVCloudAuthorizationToRequest; import org.jclouds.vcloud.director.v1_5.filters.AddVCloudAuthorizationToRequest;
import org.jclouds.vcloud.director.v1_5.functions.ThrowVCloudErrorOn4xx; import org.jclouds.vcloud.director.v1_5.functions.ThrowVCloudErrorOn4xx;
@ -40,13 +49,45 @@ import com.google.common.util.concurrent.ListenableFuture;
@RequestFilters(AddVCloudAuthorizationToRequest.class) @RequestFilters(AddVCloudAuthorizationToRequest.class)
public interface AdminVdcAsyncClient extends VdcAsyncClient { public interface AdminVdcAsyncClient extends VdcAsyncClient {
/** // TODO Should we use MetadataClient?
* @see AdminVdcClient#getVdc(URI)
*/
@GET @GET
@Consumes @Consumes
@JAXBResponseParser @JAXBResponseParser
@ExceptionParser(ThrowVCloudErrorOn4xx.class) @ExceptionParser(ThrowVCloudErrorOn4xx.class)
@Override @Override
ListenableFuture<AdminVdc> getVdc(@EndpointParam URI vdcRef); ListenableFuture<AdminVdc> getVdc(@EndpointParam URI vdcRef);
@PUT
@Consumes
@Produces(VCloudDirectorMediaType.ADMIN_VDC)
@JAXBResponseParser
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
ListenableFuture<Task> editVdc(@EndpointParam URI vdcRef, AdminVdc vdc);
@DELETE
@Consumes
@JAXBResponseParser
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
ListenableFuture<Task> deleteVdc(@EndpointParam URI vdcRef);
@POST
@Consumes
@Path("/action/enable")
@JAXBResponseParser
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
ListenableFuture<Void> enableVdc(@EndpointParam URI vdcRef);
@POST
@Consumes
@Path("/action/disable")
@JAXBResponseParser
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
ListenableFuture<Void> disableVdc(@EndpointParam URI vdcRef);
/**
* @return asynchronous access to {@link Writable} features
*/
@Delegate
MetadataAsyncClient.Writable getMetadataClient();
} }

View File

@ -22,7 +22,11 @@ import java.net.URI;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.vcloud.director.v1_5.domain.AdminVdc; import org.jclouds.vcloud.director.v1_5.domain.AdminVdc;
import org.jclouds.vcloud.director.v1_5.domain.Task;
import org.jclouds.vcloud.director.v1_5.features.MetadataAsyncClient.Writable;
/** /**
* Provides synchronous access to Network. * Provides synchronous access to Network.
@ -46,4 +50,36 @@ public interface AdminVdcClient extends VdcClient {
*/ */
@Override @Override
AdminVdc getVdc(URI vdcRef); AdminVdc getVdc(URI vdcRef);
/**
* Modifies a Virtual Data Center. Virtual Data Center could be enabled or disabled.
* Additionally it could have one of these states FAILED_CREATION(-1), NOT_READY(0),
* READY(1), UNKNOWN(1) and UNRECOGNIZED(3).
*/
Task editVdc(URI vdcRef, AdminVdc vdc);
/**
* Deletes a Virtual Data Center. The Virtual Data Center should be disabled when delete is issued.
* Otherwise error code 400 Bad Request is returned.
*/
// TODO Saw what exception, instead of 400
Task deleteVdc(URI vdcRef);
/**
* Enables a Virtual Data Center. This operation enables disabled Virtual Data Center.
* If it is already enabled this operation has no effect.
*/
void enableVdc(@EndpointParam URI vdcRef);
/**
* Disables a Virtual Data Center. If the Virtual Data Center is disabled this operation does not
* have an effect.
*/
void disableVdc(URI vdcRef);
/**
* @return synchronous access to {@link Writable} features
*/
@Delegate
MetadataClient.Writeable getMetadataClient();
} }

View File

@ -35,6 +35,9 @@ import org.jclouds.vcloud.director.v1_5.domain.Task;
* @author danikov * @author danikov
*/ */
public interface MetadataClient { public interface MetadataClient {
// FIXME Correct spelling of Writeable -> Writable
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
public static interface Readable extends MetadataClient { public static interface Readable extends MetadataClient {
/** /**

View File

@ -23,9 +23,9 @@ import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.O
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.TASK_COMPLETE_TIMELY; import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.TASK_COMPLETE_TIMELY;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkGuestCustomizationSection; import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkGuestCustomizationSection;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkNetworkConnectionSection; import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkNetworkConnectionSection;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertFalse;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
@ -38,9 +38,7 @@ import org.jclouds.vcloud.director.v1_5.domain.GuestCustomizationSection;
import org.jclouds.vcloud.director.v1_5.domain.NetworkConnectionSection; import org.jclouds.vcloud.director.v1_5.domain.NetworkConnectionSection;
import org.jclouds.vcloud.director.v1_5.domain.RasdItemsList; import org.jclouds.vcloud.director.v1_5.domain.RasdItemsList;
import org.jclouds.vcloud.director.v1_5.domain.Reference; import org.jclouds.vcloud.director.v1_5.domain.Reference;
import org.jclouds.vcloud.director.v1_5.domain.ResourceEntityType.Status;
import org.jclouds.vcloud.director.v1_5.domain.Task; import org.jclouds.vcloud.director.v1_5.domain.Task;
import org.jclouds.vcloud.director.v1_5.domain.UndeployVAppParams;
import org.jclouds.vcloud.director.v1_5.domain.VApp; import org.jclouds.vcloud.director.v1_5.domain.VApp;
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate; import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
import org.jclouds.vcloud.director.v1_5.domain.Vdc; import org.jclouds.vcloud.director.v1_5.domain.Vdc;
@ -125,7 +123,7 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
* @see #cleanUp() * @see #cleanUp()
*/ */
@BeforeClass(inheritGroups = true, description = "Cleans up the environment") @BeforeClass(inheritGroups = true, description = "Cleans up the environment")
protected void setupEnvironment() { protected void setupEnvironment() throws Exception {
// Get the configured Vdc for the tests // Get the configured Vdc for the tests
vdc = vdcClient.getVdc(vdcURI); vdc = vdcClient.getVdc(vdcURI);
assertNotNull(vdc, String.format(ENTITY_NON_NULL, VDC)); assertNotNull(vdc, String.format(ENTITY_NON_NULL, VDC));
@ -187,7 +185,7 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
// NOTE This method is also called by the BeforeClass method setupRequiredClients // NOTE This method is also called by the BeforeClass method setupRequiredClients
@AfterClass(alwaysRun = true, description = "Cleans up the environment by deleting created VApps named 'test-vapp-*' or 'new-name-*'") @AfterClass(alwaysRun = true, description = "Cleans up the environment by deleting created VApps named 'test-vapp-*' or 'new-name-*'")
protected void cleanUp() { protected void cleanUp() throws Exception {
// Find references in the Vdc with the VApp type and named 'test-vapp' or 'new-name' // Find references in the Vdc with the VApp type and named 'test-vapp' or 'new-name'
Iterable<Reference> vApps = Iterables.filter( Iterable<Reference> vApps = Iterables.filter(
vdc.getResourceEntities().getResourceEntities(), vdc.getResourceEntities().getResourceEntities(),
@ -203,25 +201,7 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
// If we found any references, delete the VApp they point to // If we found any references, delete the VApp they point to
if (vApps != null && !Iterables.isEmpty(vApps)) { if (vApps != null && !Iterables.isEmpty(vApps)) {
for (Reference ref : vApps) { for (Reference ref : vApps) {
VApp found = vAppClient.getVApp(ref.getHref()); cleanUpVApp(ref.getHref());
// debug(found);
// Shutdown and power off the VApp if necessary
if (found.getStatus().equals(Status.POWERED_ON.getValue())) {
Task shutdownTask = vAppClient.shutdown(found.getHref());
retryTaskSuccess.apply(shutdownTask);
}
// Undeploy the VApp if necessary
if (found.isDeployed()) {
UndeployVAppParams params = UndeployVAppParams.builder().build();
Task undeployTask = vAppClient.undeploy(found.getHref(), params);
retryTaskSuccess.apply(undeployTask);
}
// Delete the VApp
Task deleteTask = vAppClient.deleteVApp(found.getHref());
retryTaskSuccess.apply(deleteTask);
} }
} }
} }

View File

@ -20,11 +20,21 @@ package org.jclouds.vcloud.director.v1_5.features;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_REQ_LIVE; import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_REQ_LIVE;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.REF_REQ_LIVE; import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.REF_REQ_LIVE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.fail;
import java.net.URI;
import org.jclouds.vcloud.director.v1_5.VCloudDirectorException;
import org.jclouds.vcloud.director.v1_5.domain.AdminVdc; import org.jclouds.vcloud.director.v1_5.domain.AdminVdc;
import org.jclouds.vcloud.director.v1_5.domain.Checks; import org.jclouds.vcloud.director.v1_5.domain.Checks;
import org.jclouds.vcloud.director.v1_5.domain.Metadata;
import org.jclouds.vcloud.director.v1_5.domain.MetadataEntry;
import org.jclouds.vcloud.director.v1_5.domain.MetadataValue;
import org.jclouds.vcloud.director.v1_5.domain.Task;
import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorClientLiveTest; import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorClientLiveTest;
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;
@ -42,22 +52,177 @@ public class AdminVdcClientLiveTest extends BaseVCloudDirectorClientLiveTest {
* Convenience reference to API client. * Convenience reference to API client.
*/ */
protected AdminVdcClient vdcClient; protected AdminVdcClient vdcClient;
protected MetadataClient.Writeable metadataClient;
protected URI adminVdcUri;
private String metadataKey;
private String metadataValue;
@Override @Override
@BeforeClass(inheritGroups = true) @BeforeClass(inheritGroups = true)
public void setupRequiredClients() { public void setupRequiredClients() {
vdcClient = context.getApi().getAdminVdcClient(); vdcClient = context.getApi().getAdminVdcClient();
metadataClient = vdcClient.getMetadataClient();
assertNotNull(vdcURI, String.format(REF_REQ_LIVE, VDC));
adminVdcUri = toAdminUri(vdcURI);
}
@AfterClass(groups = { "live" })
public void cleanUp() throws Exception {
if (metadataKey != null) {
try {
Task task = metadataClient.deleteMetadataEntry(adminVdcUri, metadataKey);
assertTaskSucceeds(task);
} catch (VCloudDirectorException e) {
logger.warn(e, "Error deleting metadata-value (perhaps it doesn't exist?); continuing...");
}
}
} }
@Test(testName = "GET /admin/vdc/{id}") @Test(testName = "GET /admin/vdc/{id}")
public void testGetNetwork() { public void testGetVdc() {
// required for testing AdminVdc vdc = vdcClient.getVdc(adminVdcUri);
assertNotNull(vdcURI, String.format(REF_REQ_LIVE, VDC));
AdminVdc vdc = vdcClient.getVdc(toAdminUri(vdcURI));
assertNotNull(vdc, String.format(OBJ_REQ_LIVE, VDC)); assertNotNull(vdc, String.format(OBJ_REQ_LIVE, VDC));
// parent type // parent type
Checks.checkAdminVdc(vdc); Checks.checkAdminVdc(vdc);
} }
// TODO insufficient permissions to test
@Test(testName = "PUT /admin/vdc/{id}", enabled=false)
public void testEditVdc() throws Exception {
String origName = vdcClient.getVdc(adminVdcUri).getName();
String newName = "a"+random.nextInt(Integer.MAX_VALUE);
Exception exception = null;
AdminVdc vdc = AdminVdc.builder()
.name(newName)
.build();
try {
Task task = vdcClient.editVdc(adminVdcUri, vdc);
assertTaskSucceeds(task);
AdminVdc modified = vdcClient.getVdc(adminVdcUri);
assertEquals(modified.getName(), newName);
// parent type
Checks.checkAdminVdc(vdc);
} catch (Exception e) {
exception = e;
} finally {
try {
AdminVdc restorableVdc = AdminVdc.builder().name(origName).build();
Task task = vdcClient.editVdc(adminVdcUri, restorableVdc);
assertTaskSucceeds(task);
} catch (Exception e) {
if (exception != null) {
logger.warn(e, "Error resetting adminVdc.name; rethrowing original test exception...");
throw exception;
} else {
throw e;
}
}
}
}
// TODO insufficient permissions to test
@Test(testName = "DELETE /admin/vdc/{id}", enabled=false)
public void testDeleteVdc() throws Exception {
// TODO Need to have a VDC that we're happy to delete!
Task task = vdcClient.deleteVdc(adminVdcUri);
assertTaskSucceeds(task);
try {
vdcClient.getVdc(adminVdcUri);
} catch (VCloudDirectorException e) {
// success; unreachable because it has been deleted
}
}
// TODO insufficient permissions to test
@Test(testName = "DISABLE/ENABLE /admin/vdc/{id}", enabled=false)
public void testDisableAndEnableVdc() throws Exception {
// TODO Need to have a VDC that we're happy to delete!
Exception exception = null;
try {
vdcClient.disableVdc(adminVdcUri);
} catch (Exception e) {
exception = e;
} finally {
try {
vdcClient.enableVdc(adminVdcUri);
} catch (Exception e) {
if (exception != null) {
logger.warn(e, "Error resetting adminVdc.name; rethrowing original test exception...");
throw exception;
} else {
throw e;
}
}
}
}
@Test(testName = "PUT /admin/vdc/{id}/metadata")
public void testGetMetadata() throws Exception {
Metadata metadata = metadataClient.getMetadata(adminVdcUri);
Checks.checkMetadata(metadata);
}
// TODO insufficient permissions to test
@Test(testName = "PUT /admin/vdc/{id}/metadata", enabled=false)
public void testSetMetadata() throws Exception {
metadataKey = ""+random.nextInt(Integer.MAX_VALUE);
metadataValue = ""+random.nextInt(Integer.MAX_VALUE);
Metadata metadata = Metadata.builder()
.entry(MetadataEntry.builder().entry(metadataKey, metadataValue).build())
.build();
Task task = metadataClient.mergeMetadata(adminVdcUri, metadata);
assertTaskSucceeds(task);
MetadataValue modified = metadataClient.getMetadataValue(adminVdcUri, metadataKey);
Checks.checkMetadataValueFor("AdminVdc", modified, metadataValue);
Checks.checkMetadata(metadata);
}
// TODO insufficient permissions to test
@Test(testName = "PUT /admin/vdc/{id}/metadata", dependsOnMethods = { "testSetMetadata" }, enabled=false)
public void testGetMetadataValue() throws Exception {
MetadataValue retrievedMetadataValue = metadataClient.getMetadataValue(adminVdcUri, metadataKey);
Checks.checkMetadataValueFor("AdminVdc", retrievedMetadataValue, metadataValue);
}
// TODO insufficient permissions to test
@Test(testName = "PUT /admin/vdc/{id}/metadata", dependsOnMethods = { "testGetMetadataValue" }, enabled=false )
public void testSetMetadataValue() throws Exception {
metadataValue = ""+random.nextInt(Integer.MAX_VALUE);
MetadataValue newV = MetadataValue.builder().value(metadataValue).build();
Task task = metadataClient.setMetadata(adminVdcUri, metadataKey, newV);
assertTaskSucceeds(task);
MetadataValue retrievedMetadataValue = metadataClient.getMetadataValue(adminVdcUri, metadataKey);
Checks.checkMetadataValueFor("AdminVdc", retrievedMetadataValue, metadataValue);
}
// TODO insufficient permissions to test
@Test(testName = "PUT /admin/vdc/{id}/metadata", dependsOnMethods = { "testSetMetadataValue" }, enabled=false )
public void testDeleteMetadataValue() throws Exception {
// TODO Remove dependency on other tests; make cleanUp delete a list of metadata entries?
Task task = metadataClient.deleteMetadataEntry(adminVdcUri, metadataKey);
assertTaskSucceeds(task);
try {
metadataClient.getMetadataValue(adminVdcUri, metadataKey);
fail("Retrieval of metadata value "+metadataKey+" should have fail after deletion");
} catch (VCloudDirectorException e) {
// success; should not be accessible
}
}
} }

View File

@ -288,15 +288,34 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
assertEquals(modified.getComputerName(), computerName); assertEquals(modified.getComputerName(), computerName);
} }
@Test // FIXME deploymentLeaseInSeconds returned is null @Test
public void testEditCustomizationSection() {
boolean oldVal = vAppTemplateClient.getVAppTemplateCustomizationSection(vAppTemplateURI).isCustomizeOnInstantiate();
boolean newVal = !oldVal;
CustomizationSection customizationSection = CustomizationSection.builder()
.info("my info")
.customizeOnInstantiate(newVal)
.build();
final Task task = vAppTemplateClient.editVAppTemplateCustomizationSection(vAppTemplateURI, customizationSection);
retryTaskSuccess.apply(task);
CustomizationSection newCustomizationSection = vAppTemplateClient.getVAppTemplateCustomizationSection(vAppTemplateURI);
assertEquals(newCustomizationSection.isCustomizeOnInstantiate(), newVal);
}
@Test
public void testEditLeaseSettingsSection() throws Exception { public void testEditLeaseSettingsSection() throws Exception {
// FIXME deploymentLeaseInSeconds returned is null
//int deploymentLeaseInSeconds = random.nextInt(10000)+1;
// Note: use smallish number for storageLeaseInSeconds; it seems to be capped at 5184000? // Note: use smallish number for storageLeaseInSeconds; it seems to be capped at 5184000?
int storageLeaseInSeconds = random.nextInt(10000)+1; int storageLeaseInSeconds = random.nextInt(10000)+1;
int deploymentLeaseInSeconds = random.nextInt(10000)+1;
LeaseSettingsSection leaseSettingSection = LeaseSettingsSection.builder() LeaseSettingsSection leaseSettingSection = LeaseSettingsSection.builder()
.info("my info") .info("my info")
.storageLeaseInSeconds(storageLeaseInSeconds) .storageLeaseInSeconds(storageLeaseInSeconds)
.deploymentLeaseInSeconds(deploymentLeaseInSeconds) //.deploymentLeaseInSeconds(deploymentLeaseInSeconds)
.build(); .build();
final Task task = vAppTemplateClient.editVappTemplateLeaseSettingsSection(vAppTemplateURI, leaseSettingSection); final Task task = vAppTemplateClient.editVappTemplateLeaseSettingsSection(vAppTemplateURI, leaseSettingSection);
@ -304,7 +323,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
LeaseSettingsSection newLeaseSettingsSection = vAppTemplateClient.getVappTemplateLeaseSettingsSection(vAppTemplateURI); LeaseSettingsSection newLeaseSettingsSection = vAppTemplateClient.getVappTemplateLeaseSettingsSection(vAppTemplateURI);
assertEquals(newLeaseSettingsSection.getStorageLeaseInSeconds(), (Integer)storageLeaseInSeconds); assertEquals(newLeaseSettingsSection.getStorageLeaseInSeconds(), (Integer)storageLeaseInSeconds);
assertEquals(newLeaseSettingsSection.getDeploymentLeaseInSeconds(), (Integer)deploymentLeaseInSeconds); //assertEquals(newLeaseSettingsSection.getDeploymentLeaseInSeconds(), (Integer)deploymentLeaseInSeconds);
} }
@Test @Test