diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CaptureVAppParams.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CaptureVAppParams.java index c14684bc93..496ac063a4 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CaptureVAppParams.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CaptureVAppParams.java @@ -22,11 +22,13 @@ package org.jclouds.vcloud.director.v1_5.domain; import static com.google.common.base.Objects.equal; import static com.google.common.base.Preconditions.checkNotNull; +import java.net.URI; import java.util.Collections; import java.util.Set; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementRef; +import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import org.jclouds.vcloud.director.v1_5.domain.ovf.DeploymentOptionSection; @@ -69,6 +71,7 @@ import com.google.common.collect.Sets; "source", "sections" }) +@XmlRootElement(name = "CaptureVAppParams") public class CaptureVAppParams extends ParamsType { public static Builder builder() { return new ConcreteBuilder(); @@ -94,6 +97,16 @@ public class CaptureVAppParams extends ParamsType { return self(); } + /** + * Sets source to a new Reference that uses this URI as the href. + * + * @see CaptureVAppParams#getSource() + */ + public B source(URI source) { + this.source = Reference.builder().href(source).build(); + return self(); + } + /** * @see CaptureVAppParams#getSections() */ diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CloneVAppParams.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CloneVAppParams.java index 12bce1be2a..4fdefb9e9f 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CloneVAppParams.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CloneVAppParams.java @@ -18,6 +18,7 @@ */ package org.jclouds.vcloud.director.v1_5.domain; +import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; /** @@ -30,6 +31,7 @@ import javax.xml.bind.annotation.XmlType; * @author grkvlt@apache.org */ @XmlType(name = "CloneVAppParams") +@XmlRootElement(name = "CloneVAppParams") public class CloneVAppParams extends InstantiateVAppParamsType { public static Builder builder() { diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CloneVAppTemplateParams.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CloneVAppTemplateParams.java index 05c4e7e00a..1fa373cf26 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CloneVAppTemplateParams.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/CloneVAppTemplateParams.java @@ -21,6 +21,8 @@ package org.jclouds.vcloud.director.v1_5.domain; import static com.google.common.base.Objects.equal; +import java.net.URI; + import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @@ -81,6 +83,16 @@ public class CloneVAppTemplateParams extends ParamsType { return self(); } + /** + * Sets source to a new Reference that uses this URI as the href. + * + * @see CloneVAppTemplateParams#getSource() + */ + public B source(URI source) { + this.source = Reference.builder().href(source).build(); + return self(); + } + /** * @see CloneVAppTemplateParams#isSourceDelete() */ @@ -106,7 +118,7 @@ public class CloneVAppTemplateParams extends ParamsType { isSourceDelete = builder.isSourceDelete; } - private CloneVAppTemplateParams() { + protected CloneVAppTemplateParams() { // for JAXB } diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/InstantiateVAppParamsType.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/InstantiateVAppParamsType.java index 6f77e8203e..95af149229 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/InstantiateVAppParamsType.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/InstantiateVAppParamsType.java @@ -20,6 +20,8 @@ package org.jclouds.vcloud.director.v1_5.domain; import static com.google.common.base.Objects.equal; +import java.net.URI; + import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; @@ -64,6 +66,16 @@ public class InstantiateVAppParamsType extends VAppCreationParamsType { return self(); } + /** + * Sets source to a new Reference that uses this URI as the href. + * + * @see InstantiateVAppParamsType#getSource() + */ + public B source(URI source) { + this.source = Reference.builder().href(source).build(); + return self(); + } + /** * @see InstantiateVAppParamsType#isSourceDelete() */ diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/ResourceEntityType.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/ResourceEntityType.java index 8923b1e38b..5924b860af 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/ResourceEntityType.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/ResourceEntityType.java @@ -52,6 +52,7 @@ public abstract class ResourceEntityType extends EntityType { public static enum Status { FAILED_CREATION(-1, "The object could not be created.", true, true, true), + NOT_READY(0, "Not ready", true, false, false), // TODO duplicate code, but mentioned in `POST /vdc/{id}/action/uploadVAppTemplate` UNRESOLVED(0, "The object is unresolved.", true, true, true), RESOLVED(1, "The object is resolved.", true, true, true), DEPLOYED(2, "The object is deployed.", false, false, false), diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/SourcedCompositionItemParam.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/SourcedCompositionItemParam.java index 684016fe95..37e6c5b523 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/SourcedCompositionItemParam.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/SourcedCompositionItemParam.java @@ -79,7 +79,7 @@ public class SourcedCompositionItemParam { private Reference source; private String vAppScopedLocalId; private InstantiationParams instantiationParams; - private Set networkAssignments = Sets.newLinkedHashSet(); + private Set networkAssignment = Sets.newLinkedHashSet(); private Boolean sourceDelete; /** @@ -107,10 +107,10 @@ public class SourcedCompositionItemParam { } /** - * @see SourcedCompositionItemParam#getNetworkAssignments() + * @see SourcedCompositionItemParam#getNetworkAssignment() */ - public Builder networkAssignments(Set networkAssignments) { - this.networkAssignments = ImmutableSet.copyOf(checkNotNull(networkAssignments, "networkAssignments")); + public Builder networkAssignment(Set networkAssignment) { + this.networkAssignment = ImmutableSet.copyOf(checkNotNull(networkAssignment, "networkAssignments")); return this; } @@ -123,24 +123,24 @@ public class SourcedCompositionItemParam { } public SourcedCompositionItemParam build() { - return new SourcedCompositionItemParam(source, vAppScopedLocalId, instantiationParams, networkAssignments, sourceDelete); + return new SourcedCompositionItemParam(source, vAppScopedLocalId, instantiationParams, networkAssignment, sourceDelete); } public Builder fromSourcedCompositionItemParam(SourcedCompositionItemParam in) { return source(in.getSource()) .vAppScopedLocalId(in.getVAppScopedLocalId()) .instantiationParams(in.getInstantiationParams()) - .networkAssignments(in.getNetworkAssignments()) + .networkAssignment(in.getNetworkAssignment()) .sourceDelete(in.isSourceDelete()); } } public SourcedCompositionItemParam(Reference source, String vAppScopedLocalId, InstantiationParams instantiationParams, - Set networkAssignments, Boolean sourceDelete) { + Set networkAssignment, Boolean sourceDelete) { this.source = source; this.vAppScopedLocalId = vAppScopedLocalId; this.instantiationParams = instantiationParams; - this.networkAssignments = ImmutableSet.copyOf(networkAssignments); + this.networkAssignment = ImmutableSet.copyOf(networkAssignment); this.sourceDelete = sourceDelete; } @@ -155,7 +155,7 @@ public class SourcedCompositionItemParam { @XmlElement(name = "InstantiationParams") protected InstantiationParams instantiationParams; @XmlElement(name = "NetworkAssignment") - protected Set networkAssignments = Sets.newLinkedHashSet(); + protected Set networkAssignment = Sets.newLinkedHashSet(); @XmlAttribute protected Boolean sourceDelete; @@ -193,8 +193,8 @@ public class SourcedCompositionItemParam { /** * Gets the value of the networkAssignment property. */ - public Set getNetworkAssignments() { - return Collections.unmodifiableSet(this.networkAssignments); + public Set getNetworkAssignment() { + return Collections.unmodifiableSet(this.networkAssignment); } /** @@ -217,7 +217,7 @@ public class SourcedCompositionItemParam { return equal(source, that.source) && equal(vAppScopedLocalId, that.vAppScopedLocalId) && equal(instantiationParams, that.instantiationParams) && - equal(networkAssignments, that.networkAssignments) && + equal(networkAssignment, that.networkAssignment) && equal(sourceDelete, that.sourceDelete); } @@ -226,7 +226,7 @@ public class SourcedCompositionItemParam { return Objects.hashCode(source, vAppScopedLocalId, instantiationParams, - networkAssignments, + networkAssignment, sourceDelete); } @@ -236,7 +236,7 @@ public class SourcedCompositionItemParam { .add("source", source) .add("vAppScopedLocalId", vAppScopedLocalId) .add("instantiationParams", instantiationParams) - .add("networkAssignments", networkAssignments) + .add("networkAssignment", networkAssignment) .add("sourceDelete", sourceDelete).toString(); } diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java index 2c26f800c1..825e473072 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java @@ -78,11 +78,15 @@ import com.google.common.net.InetAddresses; public class Checks { public static void checkResourceEntityType(ResourceEntityType resourceEntity) { + checkResourceEntityType(resourceEntity, true); + } + + public static void checkResourceEntityType(ResourceEntityType resourceEntity, boolean ready) { // Check optional fields // NOTE status cannot be checked (TODO: doesn't status have a range of valid values?) Set files = resourceEntity.getFiles(); if (files != null && !files.isEmpty()) { - for (File file : files) checkFile(file); + for (File file : files) checkFile(file, ready); } // Check parent type @@ -203,13 +207,17 @@ public class Checks { // Check parent type checkEntityType(task); } - + public static void checkFile(File file) { + checkFile(file, true); + } + + public static void checkFile(File file, boolean checkSize) { // Check optional fields // NOTE checksum be checked Long size = file.getSize(); - if(size != null) { - assertTrue(file.size >= 0, "File size must be greater than or equal to 0"); + if(size != null && checkSize) { + assertTrue(size >= 0, "File size must be greater than or equal to 0, but was "+size); } Long bytesTransferred = file.getBytesTransferred(); if(bytesTransferred != null) { @@ -619,8 +627,16 @@ public class Checks { // Check parent type checkResourceEntityType(abstractVAppType); } - + public static void checkVAppTemplate(VAppTemplate template) { + checkVAppTemplate(template, true); + } + + public static void checkVAppTemplateWhenNotReady(VAppTemplate template) { + checkVAppTemplate(template, false); + } + + public static void checkVAppTemplate(VAppTemplate template, boolean ready) { // Check required fields assertNotNull(template.getName(), String.format(NOT_NULL_OBJ_FIELD_FMT, "Name", "VAppTemplate")); @@ -640,7 +656,7 @@ public class Checks { } if (template.getFiles() != null) { for (File file : template.getFiles()) { - checkFile(file); + checkFile(file, ready); } } @@ -649,7 +665,7 @@ public class Checks { // NOTE goldMaster cannot be checked // Check parent type - checkResourceEntityType(template); + checkResourceEntityType(template, ready); } public static void checkVm(Vm vm) { diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VdcClientLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VdcClientLiveTest.java index b8fd12795a..4d4d926427 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VdcClientLiveTest.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VdcClientLiveTest.java @@ -18,27 +18,46 @@ */ package org.jclouds.vcloud.director.v1_5.features; -import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.*; -import static org.jclouds.vcloud.director.v1_5.domain.Checks.*; -import static org.testng.Assert.*; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_EQ; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_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.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.util.Map; +import java.util.Set; import org.jclouds.vcloud.director.v1_5.domain.CaptureVAppParams; import org.jclouds.vcloud.director.v1_5.domain.Checks; import org.jclouds.vcloud.director.v1_5.domain.CloneVAppParams; import org.jclouds.vcloud.director.v1_5.domain.CloneVAppTemplateParams; import org.jclouds.vcloud.director.v1_5.domain.ComposeVAppParams; -import org.jclouds.vcloud.director.v1_5.domain.InstantiateVAppParams; +import org.jclouds.vcloud.director.v1_5.domain.InstantiateVAppTemplateParams; +import org.jclouds.vcloud.director.v1_5.domain.InstantiationParams; import org.jclouds.vcloud.director.v1_5.domain.Metadata; import org.jclouds.vcloud.director.v1_5.domain.MetadataValue; +import org.jclouds.vcloud.director.v1_5.domain.NetworkConfigSection; +import org.jclouds.vcloud.director.v1_5.domain.NetworkConfiguration; import org.jclouds.vcloud.director.v1_5.domain.Reference; +import org.jclouds.vcloud.director.v1_5.domain.ResourceEntityType; +import org.jclouds.vcloud.director.v1_5.domain.Task; import org.jclouds.vcloud.director.v1_5.domain.UploadVAppTemplateParams; import org.jclouds.vcloud.director.v1_5.domain.VApp; +import org.jclouds.vcloud.director.v1_5.domain.VAppNetworkConfiguration; 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.internal.BaseVCloudDirectorClientLiveTest; +import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; /** @@ -55,129 +74,140 @@ public class VdcClientLiveTest extends BaseVCloudDirectorClientLiveTest { * Convenience reference to API client. */ protected VdcClient vdcClient; + protected VAppTemplateClient vappTemplateClient; + protected VAppClient vappClient; + private VApp instantiatedVApp; + private VApp clonedVApp; + private VApp composedVApp; + private VAppTemplate clonedVAppTemplate; + private VAppTemplate capturedVAppTemplate; + private VAppTemplate uploadedVAppTemplate; + + @AfterClass(groups = { "live" }) + public void cleanUp() { + if (clonedVAppTemplate != null) { + Task task = vappTemplateClient.deleteVappTemplate(clonedVAppTemplate.getHref()); + assertTaskSucceeds(task); + } + if (capturedVAppTemplate != null) { + Task task = vappTemplateClient.deleteVappTemplate(capturedVAppTemplate.getHref()); + assertTaskSucceeds(task); + } + if (uploadedVAppTemplate != null) { + Task task = vappTemplateClient.deleteVappTemplate(uploadedVAppTemplate.getHref()); + assertTaskSucceeds(task); + } + if (instantiatedVApp != null) { + Task task = vappClient.deleteVApp(instantiatedVApp.getHref()); + assertTaskSucceeds(task); + } + if (clonedVApp != null) { + Task task = vappClient.deleteVApp(clonedVApp.getHref()); + assertTaskSucceeds(task); + } + if (composedVApp != null) { + Task task = vappClient.deleteVApp(composedVApp.getHref()); + assertTaskSucceeds(task); + } + } + @Override @BeforeClass(inheritGroups = true) public void setupRequiredClients() { vdcClient = context.getApi().getVdcClient(); + vappTemplateClient = context.getApi().getVAppTemplateClient(); + vappClient = context.getApi().getVAppClient(); + + assertNotNull(vdcURI, String.format(REF_REQ_LIVE, VDC)); } @Test(testName = "GET /vdc/{id}") public void testGetVdc() { - // required for testing - assertNotNull(vdcURI, String.format(REF_REQ_LIVE, VDC)); - Vdc vdc = vdcClient.getVdc(vdcURI); assertNotNull(vdc, String.format(OBJ_REQ_LIVE, VDC)); assertTrue(!vdc.getDescription().equals("DO NOT USE"), "vDC isn't to be used for testing"); - // parent type - Checks.checkEntityType(vdc); - - // required - assertNotNull(vdc.getAllocationModel(), String.format(OBJ_FIELD_REQ, VDC, "allocationModel")); - - assertNotNull(vdc.getStorageCapacity(), String.format(OBJ_FIELD_REQ, VDC, "storageCapacity")); - Checks.checkCapacityWithUsage(vdc.getStorageCapacity()); - - assertNotNull(vdc.getComputeCapacity(), String.format(OBJ_FIELD_REQ, VDC, "computeCapacity")); - Checks.checkComputeCapacity(vdc.getComputeCapacity()); - - assertNotNull(vdc.getNicQuota(), String.format(OBJ_FIELD_REQ, VDC, "nicQuota")); - assertTrue(vdc.getNicQuota() >= 0, String.format(OBJ_FIELD_GTE_0, VDC, "nicQuota", vdc.getNicQuota())); - - assertNotNull(vdc.getNetworkQuota(), String.format(OBJ_FIELD_REQ, VDC, "networkQuota")); - assertTrue(vdc.getNetworkQuota() >= 0, String.format(OBJ_FIELD_GTE_0, VDC, "networkQuota", vdc.getNetworkQuota())); - - - // optional - // NOTE isEnabled cannot be checked - if (vdc.getResourceEntities() != null) { - Checks.checkResourceEntities(vdc.getResourceEntities()); - } - if (vdc.getAvailableNetworks() != null) { - Checks.checkAvailableNetworks(vdc.getAvailableNetworks()); - } - if (vdc.getCapabilities() != null) { - Checks.checkCapabilities(vdc.getCapabilities()); - } - if(vdc.getVmQuota() != null) { - assertTrue(vdc.getVmQuota() >= 0, String.format(OBJ_FIELD_GTE_0, VDC, "vmQuota", vdc.getVmQuota())); - } - if(vdc.getVmQuota() != null) { - assertTrue(vdc.getVmQuota() >= 0, String.format(OBJ_FIELD_GTE_0, VDC, "vmQuota", vdc.getVmQuota())); - } + Checks.checkVdc(vdc); } - @Test(testName = "POST /vdc/{id}/action/captureVApp", enabled = false) + @Test(testName = "POST /vdc/{id}/action/captureVApp", dependsOnMethods = { "testInstantiateVAppTemplate" } ) public void testCaptureVApp() { - Reference templateSource = null; // TODO: vApp reference - VAppTemplate template = vdcClient.captureVApp(vdcURI, CaptureVAppParams.builder() - .source(templateSource) - // TODO: test optional params - //.name("") - //.description("") - //.sections(sections) // TODO: ovf sections - .build()); + String name = "captured-"+random.nextInt(Integer.MAX_VALUE); - checkVAppTemplate(template); + CaptureVAppParams captureVappParams = CaptureVAppParams.builder() + .name(name) + .source(instantiatedVApp.getHref()) + // TODO: test optional params + //.description("") + //.sections(sections) // TODO: ovf sections + .build(); - // TODO: await task to complete - // TODO: make assertions that the task was successful - } - - @Test(testName = "POST /vdc/{id}/action/cloneVApp", enabled = false) - public void testCloneVApp() { - Reference vAppSource = null; // TODO: vApp reference - VApp vApp = vdcClient.cloneVApp(vdcURI, CloneVAppParams.builder() - .source(vAppSource) - // TODO: test optional params - //.name("") - //.description("") - //.deploy(true) - //.isSourceDelete(true) - //.powerOn(true) - //.instantiationParams(InstantiationParams.builder() - // .sections(sections) // TODO: ovf sections? various tests? - // .build()) + capturedVAppTemplate = vdcClient.captureVApp(vdcURI, captureVappParams); - // Reserved. Unimplemented params; may test eventually when implemented - //.vAppParent(vAppParentRef) - //.linkedClone(true) - .build()); + Task task = Iterables.getFirst(capturedVAppTemplate.getTasks(), null); + assertTaskSucceedsLong(task); + + Checks.checkVAppTemplate(capturedVAppTemplate); - Checks.checkVApp(vApp); - - // TODO: await task to complete - // TODO: make assertions that the task was successful + assertEquals(capturedVAppTemplate.getName(), name, + String.format(OBJ_FIELD_EQ, "VAppTemplate", "name", name, capturedVAppTemplate.getName())); } - @Test(testName = "POST /vdc/{id}/action/cloneVAppTemplate", enabled = false) + @Test(testName = "POST /vdc/{id}/action/cloneVApp", dependsOnMethods = { "testInstantiateVAppTemplate" } ) + public void testCloneVApp() { + CloneVAppParams cloneVappParams = CloneVAppParams.builder() + .source(instantiatedVApp.getHref()) + // TODO: test optional params + //.name("") + //.description("") + //.deploy(true) + //.isSourceDelete(true) + //.powerOn(true) + //.instantiationParams(InstantiationParams.builder() + // .sections(sections) // TODO: ovf sections? various tests? + // .build()) + + // Reserved. Unimplemented params; may test eventually when implemented + //.vAppParent(vAppParentRef) + //.linkedClone(true) + .build(); + + clonedVApp = vdcClient.cloneVApp(vdcURI, cloneVappParams); + + Task task = Iterables.getFirst(clonedVApp.getTasks(), null); + assertNotNull(task, "vdcClient.cloneVApp returned VApp that did not contain any tasks"); + assertTaskSucceedsLong(task); + + Checks.checkVApp(clonedVApp); + } + + @Test(testName = "POST /vdc/{id}/action/cloneVAppTemplate") public void testCloneVAppTemplate() { - Reference templateSource = null; // TODO: vAppTemplate reference - VAppTemplate template = vdcClient.cloneVAppTemplate(vdcURI, CloneVAppTemplateParams.builder() - .source(templateSource) - // TODO: test optional params - //.name("") - //.description("") - //.isSourceDelete(true) - //.sections(sections) // TODO: ovf sections - .build()); + clonedVAppTemplate = vdcClient.cloneVAppTemplate(vdcURI, CloneVAppTemplateParams.builder() + .source(vAppTemplateURI) + .build()); - Checks.checkVAppTemplate(template); + Task task = Iterables.getFirst(clonedVAppTemplate.getTasks(), null); + assertNotNull(task, "vdcClient.cloneVAppTemplate returned VAppTemplate that did not contain any tasks"); + assertTaskSucceedsLong(task); - // TODO: await task to complete - // TODO: make assertions that the task was successful + Checks.checkVAppTemplate(clonedVAppTemplate); } - @Test(testName = "POST /vdc/{id}/action/composeVApp", enabled = false) + @Test(testName = "POST /vdc/{id}/action/composeVApp") public void testComposeVApp() { - VApp vApp = vdcClient.composeVApp(vdcURI, ComposeVAppParams.builder() + String name = "composed-"+random.nextInt(Integer.MAX_VALUE); + + composedVApp = vdcClient.composeVApp(vdcURI, ComposeVAppParams.builder() + .name(name) // TODO: test optional params - //.name("") + //.sourcedItem(SourcedCompositionItemParam.builder() + //.sourcedItem(vAppTemplateURI) + //.build()) //.description("") //.deploy(true) - //.isSourceDelete(true) + //.isSourceDelete(false) //.powerOn(true) //.instantiationParams(InstantiationParams.builder() // .sections(sections) // TODO: ovf sections? various tests? @@ -186,49 +216,104 @@ public class VdcClientLiveTest extends BaseVCloudDirectorClientLiveTest { // Reserved. Unimplemented params; may test eventually when implemented //.linkedClone() .build()); - - Checks.checkVApp(vApp); - - // TODO: await task to complete - // TODO: make assertions that the task was successful + + Task task = Iterables.getFirst(composedVApp.getTasks(), null); + assertNotNull(task, "vdcClient.composeVApp returned VApp that did not contain any tasks"); + assertTaskSucceedsLong(task); + + Checks.checkVApp(composedVApp); + assertEquals(composedVApp.getName(), name, + String.format(OBJ_FIELD_EQ, "VApp", "name", name, composedVApp.getName())); } - @Test(testName = "POST /vdc/{id}/action/instantiateVAppTemplate", enabled = false) + // TODO Duplicates code in VAppClientLiveTest + @Test(testName = "POST /vdc/{id}/action/instantiateVAppTemplate") public void testInstantiateVAppTemplate() { - Reference templateSource = null; // TODO: vApp or vAppTemplate reference - VApp vApp = vdcClient.instantiateVApp(vdcURI, InstantiateVAppParams.builder() - .source(templateSource) - // TODO: test optional params - //.name("") - //.description("") - //.isSourceDelete(true) - .build()); + Vdc vdc = vdcClient.getVdc(vdcURI); + + Set networks = vdc.getAvailableNetworks().getNetworks(); + Optional parentNetwork = Iterables.tryFind( + networks, new Predicate() { + @Override + public boolean apply(Reference reference) { + return reference.getHref().equals(networkURI); + } + }); + + if (!parentNetwork.isPresent()) { + fail(String.format("Could not find network %s in vdc", networkURI.toASCIIString())); + } + + NetworkConfiguration networkConfiguration = NetworkConfiguration.builder() + .parentNetwork(parentNetwork.get()) + .fenceMode("bridged") + .build(); - Checks.checkVApp(vApp); + NetworkConfigSection networkConfigSection = NetworkConfigSection.builder() + .info("Configuration parameters for logical networks") + .networkConfigs( + ImmutableSet.of(VAppNetworkConfiguration.builder() + .networkName("vAppNetwork") + .configuration(networkConfiguration) + .build())) + .build(); + + InstantiationParams instantiationParams = InstantiationParams.builder() + .sections(ImmutableSet.of(networkConfigSection)) + .build(); + + InstantiateVAppTemplateParams instantiate = InstantiateVAppTemplateParams.builder() + .name("test-vapp-"+random.nextInt(Integer.MAX_VALUE)) + .notDeploy() + .notPowerOn() + .description("Test VApp") + .instantiationParams(instantiationParams) + .source(vAppTemplateURI) + .build(); + + instantiatedVApp = vdcClient.instantiateVApp(vdcURI, instantiate); + Task instantiationTask = Iterables.getFirst(instantiatedVApp.getTasks(), null); + assertTaskSucceedsLong(instantiationTask); - // TODO: await task to complete - // TODO: make assertions that the task was successful + Checks.checkVApp(instantiatedVApp); } - @Test(testName = "POST /vdc/{id}/action/uploadVAppTemplate", enabled = false) + @Test(testName = "POST /vdc/{id}/action/uploadVAppTemplate") public void testUploadVAppTemplate() { - VAppTemplate template = vdcClient.uploadVAppTemplate(vdcURI, UploadVAppTemplateParams.builder() - // TODO: test optional params - //.name("") - //.description("") - //.transferFormat("") - //.manifestRequired(true) - .build()); + // TODO Should test all 4 stages of upload; currently doing only stage 1 here. + // 1. creating empty vApp template entity + // 2. uploading an OVF of vApp template + // 3. uploading disks described from the OVF + // 4. finishing task for uploading - Checks.checkVAppTemplate(template); + String name = "uploaded-"+random.nextInt(Integer.MAX_VALUE); + + UploadVAppTemplateParams uploadVAppTemplateParams = UploadVAppTemplateParams.builder() + .name(name) + // TODO: test optional params + //.description("") + //.transferFormat("") + //.manifestRequired(true) + .build(); + + uploadedVAppTemplate = vdcClient.uploadVAppTemplate(vdcURI, uploadVAppTemplateParams); + + Checks.checkVAppTemplateWhenNotReady(uploadedVAppTemplate); + + assertEquals(uploadedVAppTemplate.getName(), name, + String.format(OBJ_FIELD_EQ, "VAppTemplate", "name", name, uploadedVAppTemplate.getName())); + + ResourceEntityType.Status expectedStatus = ResourceEntityType.Status.NOT_READY; + Integer actualStatus = uploadedVAppTemplate.getStatus(); + assertEquals(actualStatus, expectedStatus.getValue(), + String.format(OBJ_FIELD_EQ, "VAppTemplate", "status", expectedStatus, actualStatus)); - // TODO: await task to complete - // TODO: make assertions that the task was successful } - @Test(testName = "GET /network/{id}/metadata", enabled = false) + @Test(testName = "GET /network/{id}/metadata") public void testGetMetadata() { Metadata metadata = vdcClient.getMetadataClient().getMetadata(vdcURI); + // required for testing assertFalse(Iterables.isEmpty(metadata.getMetadataEntries()), String.format(OBJ_FIELD_REQ_LIVE, VDC, "metadata.entries")); @@ -236,10 +321,16 @@ public class VdcClientLiveTest extends BaseVCloudDirectorClientLiveTest { Checks.checkMetadataFor(VDC, metadata); } - @Test(testName = "GET /network/{id}/metadata/{key}", enabled = false) + @Test(testName = "GET /network/{id}/metadata/{key}", dependsOnMethods = { "testGetMetadata" } ) public void testGetMetadataValue() { - MetadataValue metadataValue = vdcClient.getMetadataClient().getMetadataValue(vdcURI, "key"); + // First find a key + Metadata metadata = vdcClient.getMetadataClient().getMetadata(vdcURI); + Map metadataMap = Checks.metadataToMap(metadata); + String key = Iterables.getFirst(metadataMap.keySet(), "MadeUpKey!"); + String value = metadataMap.get(key); - Checks.checkMetadataValueFor(VDC, metadataValue); + MetadataValue metadataValue = vdcClient.getMetadataClient().getMetadataValue(vdcURI, key); + + Checks.checkMetadataValueFor(VDC, metadataValue, value); } } diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/BaseVCloudDirectorClientLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/BaseVCloudDirectorClientLiveTest.java index d90ddc0f07..a170d6f8f7 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/BaseVCloudDirectorClientLiveTest.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/internal/BaseVCloudDirectorClientLiveTest.java @@ -19,9 +19,11 @@ package org.jclouds.vcloud.director.v1_5.internal; import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; import java.net.URI; import java.util.Properties; +import java.util.Random; import javax.inject.Inject; @@ -124,6 +126,8 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ protected URI vdcURI; protected URI userURI; + protected Random random = new Random(); + // TODO change properties to URI, not id @SuppressWarnings("unchecked") protected void initTestParametersFromPropertiesOrLazyDiscover() { @@ -183,4 +187,12 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ public URI toAdminUri(URI uri) { return Reference.builder().href(uri).build().toAdminReference(endpoint).getHref(); } + + protected void assertTaskSucceeds(Task task) { + assertTrue(retryTaskSuccess.apply(task)); + } + + protected void assertTaskSucceedsLong(Task task) { + assertTrue(retryTaskSuccessLong.apply(task)); + } }