Merge pull request #506 from danikov/vclouds-director-bugfixes-3

Issue 830: vCloud director Bugfixs
This commit is contained in:
Adrian Cole 2012-03-21 10:17:50 -07:00
commit 35dc8f1224
6 changed files with 231 additions and 12 deletions

View File

@ -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
*
*
* <p>Java class for References complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* &lt;complexType name="References">
* &lt;complexContent>
* &lt;extension base="{http://www.vmware.com/vcloud/v1.5}ContainerType">
* &lt;sequence>
* &lt;element ref="{http://www.vmware.com/vcloud/v1.5}Reference" maxOccurs="unbounded" minOccurs="0"/>
* &lt;/sequence>
* &lt;anyAttribute processContents='lax' namespace='##other'/>
* &lt;/extension>
* &lt;/complexContent>
* &lt;/complexType>
* </pre>
*
*
*/
@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<ConcreteBuilder> {
@Override
protected ConcreteBuilder self() {
return this;
}
}
public abstract static class Builder<T extends Builder<T>> extends ContainerType.Builder<T> {
private Set<Reference> references;
/**
* @see References#getReference()
*/
public T references(Set<Reference> 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<Reference> references = Sets.newLinkedHashSet();
/**
* Gets the value of the reference property.
*
* <p>
* 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 <CODE>set</CODE> method for the reference property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getReference().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link JAXBElement }{@code <}{@link ReferenceType }{@code >}
*
*
*/
public Set<Reference> 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);
}
}

View File

@ -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<Task> editProductSectionsForVAppTemplate(@EndpointParam URI templateURI,
@BinderParam(BindToXMLPayload.class) ProductSectionList sections);
// TODO shadowVms
/**
* @see VAppTemplateClient#getShadowVms(URI)
*/
@GET
@Consumes
@Path("/shadowVms")
@JAXBResponseParser
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
ListenableFuture<References> getShadowVms(@EndpointParam URI templateURI);
/**
* @return asynchronous access to {@link Metadata} features

View File

@ -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
/**
* <pre>
* GET /vAppTemplate/{id}/shadowVms
* </pre>
*
* @param templateUri the URI of the template
* @return shadowVM references
*/
References getShadowVms(URI templateUri);
/**
* @return synchronous access to {@link Metadata} features

View File

@ -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);
}
}

View File

@ -81,7 +81,7 @@ public class OrgClientLiveTest extends BaseVCloudDirectorClientLiveTest {
private Org org;
private boolean metadataSet = false;
@Test(testName = "GET /org/")
@Test(testName = "GET /org")
public void testGetOrgList() {
// Call the method being tested
orgList = orgClient.getOrgList();
@ -117,7 +117,7 @@ public class OrgClientLiveTest extends BaseVCloudDirectorClientLiveTest {
metadataSet = true;
}
@Test(testName = "GET /org/{id}/metadata/", dependsOnMethods = { "testSetupMetadata" })
@Test(testName = "GET /org/{id}/metadata", dependsOnMethods = { "testSetupMetadata" })
public void testGetOrgMetadata() {
// Call the method being tested
Metadata metadata = orgClient.getMetadataClient().getMetadata(orgURI);

View File

@ -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")