From f99302b1e6846664d7d6746d2384022755220da2 Mon Sep 17 00:00:00 2001 From: danikov Date: Wed, 21 Mar 2012 17:03:53 +0000 Subject: [PATCH] implement shadow vas + order tests to guarantee success --- .../director/v1_5/domain/References.java | 163 ++++++++++++++++++ .../features/VAppTemplateAsyncClient.java | 13 +- .../v1_5/features/VAppTemplateClient.java | 13 +- .../vcloud/director/v1_5/domain/Checks.java | 28 +++ .../features/VAppTemplateClientLiveTest.java | 22 ++- 5 files changed, 229 insertions(+), 10 deletions(-) create mode 100644 labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/References.java diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/References.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/References.java new file mode 100644 index 0000000000..195328a726 --- /dev/null +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/References.java @@ -0,0 +1,163 @@ +/** + * 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.vcloud.director.v1_5.domain; + +import static com.google.common.base.Objects.equal; + +import java.util.Set; + +import javax.lang.model.type.ReferenceType; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +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.query.ContainerType; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; +import com.google.common.collect.Sets; + + +/** + * + * This is the container for returned elements in referenceView + * + * + *

Java class for References complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="References">
+ *   <complexContent>
+ *     <extension base="{http://www.vmware.com/vcloud/v1.5}ContainerType">
+ *       <sequence>
+ *         <element ref="{http://www.vmware.com/vcloud/v1.5}Reference" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *       <anyAttribute processContents='lax' namespace='##other'/>
+ *     </extension>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "References") +@XmlType(propOrder = { + "references" +}) +public class References extends ContainerType { + public static Builder builder() { + return new ConcreteBuilder(); + } + + public Builder toBuilder() { + return new ConcreteBuilder().fromReferences(this); + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + + public abstract static class Builder> extends ContainerType.Builder { + private Set references; + + /** + * @see References#getReference() + */ + public T references(Set references) { + this.references = references; + return self(); + } + + public References build() { + return new References(this); + } + + public T fromReferences(References in) { + return fromContainerType(in) + .references(in.getReferences()); + } + } + + private References(Builder b) { + super(b); + this.references = b.references; + } + + + @XmlElementRef(name = "Reference", namespace = "http://www.vmware.com/vcloud/v1.5") + protected Set references = Sets.newLinkedHashSet(); + + /** + * Gets the value of the reference property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the reference property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getReference().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link JAXBElement }{@code <}{@link ReferenceType }{@code >} + * + * + */ + public Set getReferences() { + return this.references; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + References that = References.class.cast(o); + return super.equals(that) && equal(references, that.references); + } + + @Override + public int hashCode() { + return Objects.hashCode(super.hashCode(), references); + } + + @Override + public ToStringHelper string() { + return super.string() + .add("references", references); + } + +} diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateAsyncClient.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateAsyncClient.java index c07b425d13..d2c400c474 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateAsyncClient.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateAsyncClient.java @@ -59,6 +59,7 @@ import org.jclouds.vcloud.director.v1_5.domain.NetworkConfigSection; import org.jclouds.vcloud.director.v1_5.domain.NetworkConnectionSection; import org.jclouds.vcloud.director.v1_5.domain.Owner; import org.jclouds.vcloud.director.v1_5.domain.ProductSectionList; +import org.jclouds.vcloud.director.v1_5.domain.References; import org.jclouds.vcloud.director.v1_5.domain.RelocateParams; import org.jclouds.vcloud.director.v1_5.domain.Task; import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate; @@ -362,8 +363,16 @@ public interface VAppTemplateAsyncClient { @ExceptionParser(ThrowVCloudErrorOn4xx.class) ListenableFuture editProductSectionsForVAppTemplate(@EndpointParam URI templateURI, @BinderParam(BindToXMLPayload.class) ProductSectionList sections); - - // TODO shadowVms + + /** + * @see VAppTemplateClient#getShadowVms(URI) + */ + @GET + @Consumes + @Path("/shadowVms") + @JAXBResponseParser + @ExceptionParser(ThrowVCloudErrorOn4xx.class) + ListenableFuture getShadowVms(@EndpointParam URI templateURI); /** * @return asynchronous access to {@link Metadata} features diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateClient.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateClient.java index bf52ddb6ae..68bb19dd3d 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateClient.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateClient.java @@ -31,6 +31,7 @@ import org.jclouds.vcloud.director.v1_5.domain.NetworkConfigSection; import org.jclouds.vcloud.director.v1_5.domain.NetworkConnectionSection; import org.jclouds.vcloud.director.v1_5.domain.Owner; import org.jclouds.vcloud.director.v1_5.domain.ProductSectionList; +import org.jclouds.vcloud.director.v1_5.domain.References; import org.jclouds.vcloud.director.v1_5.domain.RelocateParams; import org.jclouds.vcloud.director.v1_5.domain.Task; import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate; @@ -348,8 +349,16 @@ public interface VAppTemplateClient { * should monitor the returned task status in order to check when it is completed. */ Task editProductSectionsForVAppTemplate(URI templateUri, ProductSectionList sections); - - // TODO ShadowVms + + /** + *

+    * GET /vAppTemplate/{id}/shadowVms
+    * 
+ * + * @param templateUri the URI of the template + * @return shadowVM references + */ + References getShadowVms(URI templateUri); /** * @return synchronous access to {@link Metadata} features 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 b3c74f8fcd..63307f2905 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 @@ -63,6 +63,7 @@ import org.jclouds.vcloud.director.v1_5.domain.ovf.StartupSection; import org.jclouds.vcloud.director.v1_5.domain.ovf.VirtualHardwareSection; import org.jclouds.vcloud.director.v1_5.domain.ovf.VirtualSystem; import org.jclouds.vcloud.director.v1_5.domain.ovf.environment.EnvironmentType; +import org.jclouds.vcloud.director.v1_5.domain.query.ContainerType; import org.jclouds.vcloud.director.v1_5.domain.query.QueryResultRecordType; import com.beust.jcommander.internal.Maps; @@ -1497,4 +1498,31 @@ public class Checks { checkType(record.getType()); } } + + public static void checkReferences(References references) { + // optional + for (Reference reference : references.getReferences()) { + checkReferenceType(reference); + } + + // parent type + checkContainerType(references); + } + + public static void checkContainerType(ContainerType container) { + // optional + // NOTE name can't be checked + if (container.getPage() != null) { + assertTrue(container.getPage() >= 1, "page must be >=1 "); + } + if (container.getPageSize() != null) { + assertTrue(container.getPageSize() >= 1, "pageSize must be >=1 "); + } + if (container.getTotal() != null) { + assertTrue(container.getTotal() >= 0, "total must be >=0 "); + } + + // parent type + checkResourceType(container); + } } diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateClientLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateClientLiveTest.java index 3e1c83aec3..2306bf4607 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateClientLiveTest.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/VAppTemplateClientLiveTest.java @@ -42,6 +42,7 @@ import java.util.Map; import java.util.Set; import org.jclouds.vcloud.director.v1_5.VCloudDirectorException; +import org.jclouds.vcloud.director.v1_5.domain.Checks; import org.jclouds.vcloud.director.v1_5.domain.CloneVAppTemplateParams; import org.jclouds.vcloud.director.v1_5.domain.CustomizationSection; import org.jclouds.vcloud.director.v1_5.domain.GuestCustomizationSection; @@ -55,6 +56,7 @@ import org.jclouds.vcloud.director.v1_5.domain.NetworkConnectionSection; import org.jclouds.vcloud.director.v1_5.domain.Owner; import org.jclouds.vcloud.director.v1_5.domain.ProductSectionList; import org.jclouds.vcloud.director.v1_5.domain.Reference; +import org.jclouds.vcloud.director.v1_5.domain.References; import org.jclouds.vcloud.director.v1_5.domain.RelocateParams; import org.jclouds.vcloud.director.v1_5.domain.Task; import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate; @@ -154,7 +156,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest { checkLeaseSettingsSection(leaseSettingsSection); } - @Test(testName = "GET /vAppTemplate/{id}/metadata") + @Test(testName = "GET /vAppTemplate/{id}/metadata", dependsOnMethods = { "testEditMetadataValue" }) public void testGetVAppTemplateMetadata() { Metadata metadata = vAppTemplateClient.getMetadataClient().getMetadata(vAppTemplateURI); @@ -162,7 +164,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest { } // implicitly tested by testEditVAppTemplateMetadataValue, which first creates the metadata entry; otherwise no entry may exist - @Test(testName = "GET /vAppTemplate/{id}/metadata/{key}") + @Test(testName = "GET /vAppTemplate/{id}/metadata/{key}", dependsOnMethods = { "testGetVAppTemplateMetadata" }) public void testGetMetadataValue() { Metadata metadata = vAppTemplateClient.getMetadataClient().getMetadata(vAppTemplateURI); MetadataEntry entry = Iterables.get(metadata.getMetadataEntries(), 0); @@ -221,7 +223,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest { assertEquals(newTemplate.getDescription(), description); } - @Test(testName = "POST /vAppTemplate/{id}/metadata") + @Test(testName = "POST /vAppTemplate/{id}/metadata", dependsOnMethods = { "testGetVAppTemplate" }) public void testEditMetadata() { // TODO Cleanup after ourselves.. @@ -244,7 +246,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest { checkMetadataFor("vAppTemplate", newMetadata, expectedMetadataMap); } - @Test(testName = "PUT /vAppTemplate/{id}/metadata/{key}") + @Test(testName = "PUT /vAppTemplate/{id}/metadata/{key}", dependsOnMethods = { "testEditMetadata" }) public void testEditMetadataValue() { // TODO Cleanup after ourselves.. @@ -259,7 +261,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest { assertEquals(newMetadataValue.getValue(), metadataValue.getValue()); } - @Test(testName = "DELETE /vAppTemplate/{id}/metadata/{key}") + @Test(testName = "DELETE /vAppTemplate/{id}/metadata/{key}", dependsOnMethods = { "testGetMetadataValue" }) public void testDeleteVAppTemplateMetadataValue() { // First store a value String key = name("key-"); @@ -379,7 +381,8 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest { checkNetworkConnectionSection(modified); } - @Test(testName = "DELETE /vAppTemplate/{id}") // FIXME cloneVAppTemplate is giving back 500 error + // FIXME cloneVAppTemplate is giving back 500 error + @Test(testName = "DELETE /vAppTemplate/{id}", dependsOnMethods = { "testGetVAppTemplate" }) public void testDeleteVAppTemplate() throws Exception { VAppTemplate clonedVappTemplate = cloneVAppTemplate(true); @@ -461,6 +464,13 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest { assertTaskSucceedsLong(task); } + @Test(testName = "GET /vAppTemplate/{id}/shadowVms") + public void testGetShadowVms() { + References references = vAppTemplateClient.getShadowVms(vAppTemplateURI); + + Checks.checkReferences(references); + } + // This failed previously, but is passing now. // However, it's not part of the official API so not necessary to assert it. @Test(testName = "test completed task not included in vAppTemplate")