mirror of https://github.com/apache/jclouds.git
Merge pull request #488 from aledsage/issue-830-vdc-admin-strike2
Issue #830 vcloud-director: vdc admin client
This commit is contained in:
commit
ee2a7e96ba
|
@ -21,13 +21,22 @@ package org.jclouds.vcloud.director.v1_5.features;
|
|||
import java.net.URI;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
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.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.JAXBResponseParser;
|
||||
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.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.functions.ThrowVCloudErrorOn4xx;
|
||||
|
||||
|
@ -40,13 +49,45 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
@RequestFilters(AddVCloudAuthorizationToRequest.class)
|
||||
public interface AdminVdcAsyncClient extends VdcAsyncClient {
|
||||
|
||||
/**
|
||||
* @see AdminVdcClient#getVdc(URI)
|
||||
*/
|
||||
// TODO Should we use MetadataClient?
|
||||
|
||||
@GET
|
||||
@Consumes
|
||||
@JAXBResponseParser
|
||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,11 @@ import java.net.URI;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
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.Task;
|
||||
import org.jclouds.vcloud.director.v1_5.features.MetadataAsyncClient.Writable;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Network.
|
||||
|
@ -46,4 +50,36 @@ public interface AdminVdcClient extends VdcClient {
|
|||
*/
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ import org.jclouds.vcloud.director.v1_5.domain.Task;
|
|||
* @author danikov
|
||||
*/
|
||||
public interface MetadataClient {
|
||||
|
||||
// FIXME Correct spelling of Writeable -> Writable
|
||||
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public static interface Readable extends MetadataClient {
|
||||
/**
|
||||
|
|
|
@ -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.domain.Checks.checkGuestCustomizationSection;
|
||||
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.assertTrue;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
|
||||
import java.io.IOException;
|
||||
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.RasdItemsList;
|
||||
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.UndeployVAppParams;
|
||||
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.Vdc;
|
||||
|
@ -125,7 +123,7 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
|
|||
* @see #cleanUp()
|
||||
*/
|
||||
@BeforeClass(inheritGroups = true, description = "Cleans up the environment")
|
||||
protected void setupEnvironment() {
|
||||
protected void setupEnvironment() throws Exception {
|
||||
// Get the configured Vdc for the tests
|
||||
vdc = vdcClient.getVdc(vdcURI);
|
||||
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
|
||||
@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'
|
||||
Iterable<Reference> vApps = Iterables.filter(
|
||||
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 (vApps != null && !Iterables.isEmpty(vApps)) {
|
||||
for (Reference ref : vApps) {
|
||||
VApp found = vAppClient.getVApp(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);
|
||||
cleanUpVApp(ref.getHref());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.REF_REQ_LIVE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
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.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.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -42,22 +52,177 @@ public class AdminVdcClientLiveTest extends BaseVCloudDirectorClientLiveTest {
|
|||
* Convenience reference to API client.
|
||||
*/
|
||||
protected AdminVdcClient vdcClient;
|
||||
|
||||
protected MetadataClient.Writeable metadataClient;
|
||||
|
||||
protected URI adminVdcUri;
|
||||
|
||||
private String metadataKey;
|
||||
private String metadataValue;
|
||||
|
||||
@Override
|
||||
@BeforeClass(inheritGroups = true)
|
||||
public void setupRequiredClients() {
|
||||
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}")
|
||||
public void testGetNetwork() {
|
||||
// required for testing
|
||||
assertNotNull(vdcURI, String.format(REF_REQ_LIVE, VDC));
|
||||
|
||||
AdminVdc vdc = vdcClient.getVdc(toAdminUri(vdcURI));
|
||||
public void testGetVdc() {
|
||||
AdminVdc vdc = vdcClient.getVdc(adminVdcUri);
|
||||
assertNotNull(vdc, String.format(OBJ_REQ_LIVE, VDC));
|
||||
|
||||
// parent type
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -288,15 +288,34 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
|
|||
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 {
|
||||
// FIXME deploymentLeaseInSeconds returned is null
|
||||
//int deploymentLeaseInSeconds = random.nextInt(10000)+1;
|
||||
|
||||
// Note: use smallish number for storageLeaseInSeconds; it seems to be capped at 5184000?
|
||||
int storageLeaseInSeconds = random.nextInt(10000)+1;
|
||||
int deploymentLeaseInSeconds = random.nextInt(10000)+1;
|
||||
LeaseSettingsSection leaseSettingSection = LeaseSettingsSection.builder()
|
||||
.info("my info")
|
||||
.storageLeaseInSeconds(storageLeaseInSeconds)
|
||||
.deploymentLeaseInSeconds(deploymentLeaseInSeconds)
|
||||
//.deploymentLeaseInSeconds(deploymentLeaseInSeconds)
|
||||
.build();
|
||||
|
||||
final Task task = vAppTemplateClient.editVappTemplateLeaseSettingsSection(vAppTemplateURI, leaseSettingSection);
|
||||
|
@ -304,7 +323,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
|
|||
|
||||
LeaseSettingsSection newLeaseSettingsSection = vAppTemplateClient.getVappTemplateLeaseSettingsSection(vAppTemplateURI);
|
||||
assertEquals(newLeaseSettingsSection.getStorageLeaseInSeconds(), (Integer)storageLeaseInSeconds);
|
||||
assertEquals(newLeaseSettingsSection.getDeploymentLeaseInSeconds(), (Integer)deploymentLeaseInSeconds);
|
||||
//assertEquals(newLeaseSettingsSection.getDeploymentLeaseInSeconds(), (Integer)deploymentLeaseInSeconds);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue