mirror of https://github.com/apache/jclouds.git
Merge pull request #506 from danikov/vclouds-director-bugfixes-3
Issue 830: vCloud director Bugfixs
This commit is contained in:
commit
35dc8f1224
|
@ -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>
|
||||||
|
* <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>
|
||||||
|
* </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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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.NetworkConnectionSection;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.Owner;
|
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.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.RelocateParams;
|
||||||
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.VAppTemplate;
|
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
|
||||||
|
@ -363,7 +364,15 @@ public interface VAppTemplateAsyncClient {
|
||||||
ListenableFuture<Task> editProductSectionsForVAppTemplate(@EndpointParam URI templateURI,
|
ListenableFuture<Task> editProductSectionsForVAppTemplate(@EndpointParam URI templateURI,
|
||||||
@BinderParam(BindToXMLPayload.class) ProductSectionList sections);
|
@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
|
* @return asynchronous access to {@link Metadata} features
|
||||||
|
|
|
@ -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.NetworkConnectionSection;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.Owner;
|
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.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.RelocateParams;
|
||||||
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.VAppTemplate;
|
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
|
||||||
|
@ -349,7 +350,15 @@ public interface VAppTemplateClient {
|
||||||
*/
|
*/
|
||||||
Task editProductSectionsForVAppTemplate(URI templateUri, ProductSectionList sections);
|
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
|
* @return synchronous access to {@link Metadata} features
|
||||||
|
|
|
@ -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.VirtualHardwareSection;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.ovf.VirtualSystem;
|
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.ovf.environment.EnvironmentType;
|
||||||
|
import org.jclouds.vcloud.director.v1_5.domain.query.ContainerType;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.query.QueryResultRecordType;
|
import org.jclouds.vcloud.director.v1_5.domain.query.QueryResultRecordType;
|
||||||
|
|
||||||
import com.beust.jcommander.internal.Maps;
|
import com.beust.jcommander.internal.Maps;
|
||||||
|
@ -1497,4 +1498,31 @@ public class Checks {
|
||||||
checkType(record.getType());
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class OrgClientLiveTest extends BaseVCloudDirectorClientLiveTest {
|
||||||
private Org org;
|
private Org org;
|
||||||
private boolean metadataSet = false;
|
private boolean metadataSet = false;
|
||||||
|
|
||||||
@Test(testName = "GET /org/")
|
@Test(testName = "GET /org")
|
||||||
public void testGetOrgList() {
|
public void testGetOrgList() {
|
||||||
// Call the method being tested
|
// Call the method being tested
|
||||||
orgList = orgClient.getOrgList();
|
orgList = orgClient.getOrgList();
|
||||||
|
@ -117,7 +117,7 @@ public class OrgClientLiveTest extends BaseVCloudDirectorClientLiveTest {
|
||||||
metadataSet = true;
|
metadataSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(testName = "GET /org/{id}/metadata/", dependsOnMethods = { "testSetupMetadata" })
|
@Test(testName = "GET /org/{id}/metadata", dependsOnMethods = { "testSetupMetadata" })
|
||||||
public void testGetOrgMetadata() {
|
public void testGetOrgMetadata() {
|
||||||
// Call the method being tested
|
// Call the method being tested
|
||||||
Metadata metadata = orgClient.getMetadataClient().getMetadata(orgURI);
|
Metadata metadata = orgClient.getMetadataClient().getMetadata(orgURI);
|
||||||
|
|
|
@ -42,6 +42,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorException;
|
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.CloneVAppTemplateParams;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.CustomizationSection;
|
import org.jclouds.vcloud.director.v1_5.domain.CustomizationSection;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.GuestCustomizationSection;
|
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.Owner;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.ProductSectionList;
|
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.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.RelocateParams;
|
||||||
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.VAppTemplate;
|
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
|
||||||
|
@ -154,7 +156,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
|
||||||
checkLeaseSettingsSection(leaseSettingsSection);
|
checkLeaseSettingsSection(leaseSettingsSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(testName = "GET /vAppTemplate/{id}/metadata")
|
@Test(testName = "GET /vAppTemplate/{id}/metadata", dependsOnMethods = { "testEditMetadataValue" })
|
||||||
public void testGetVAppTemplateMetadata() {
|
public void testGetVAppTemplateMetadata() {
|
||||||
Metadata metadata = vAppTemplateClient.getMetadataClient().getMetadata(vAppTemplateURI);
|
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
|
// 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() {
|
public void testGetMetadataValue() {
|
||||||
Metadata metadata = vAppTemplateClient.getMetadataClient().getMetadata(vAppTemplateURI);
|
Metadata metadata = vAppTemplateClient.getMetadataClient().getMetadata(vAppTemplateURI);
|
||||||
MetadataEntry entry = Iterables.get(metadata.getMetadataEntries(), 0);
|
MetadataEntry entry = Iterables.get(metadata.getMetadataEntries(), 0);
|
||||||
|
@ -221,7 +223,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
|
||||||
assertEquals(newTemplate.getDescription(), description);
|
assertEquals(newTemplate.getDescription(), description);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(testName = "POST /vAppTemplate/{id}/metadata")
|
@Test(testName = "POST /vAppTemplate/{id}/metadata", dependsOnMethods = { "testGetVAppTemplate" })
|
||||||
public void testEditMetadata() {
|
public void testEditMetadata() {
|
||||||
// TODO Cleanup after ourselves..
|
// TODO Cleanup after ourselves..
|
||||||
|
|
||||||
|
@ -244,7 +246,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
|
||||||
checkMetadataFor("vAppTemplate", newMetadata, expectedMetadataMap);
|
checkMetadataFor("vAppTemplate", newMetadata, expectedMetadataMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(testName = "PUT /vAppTemplate/{id}/metadata/{key}")
|
@Test(testName = "PUT /vAppTemplate/{id}/metadata/{key}", dependsOnMethods = { "testEditMetadata" })
|
||||||
public void testEditMetadataValue() {
|
public void testEditMetadataValue() {
|
||||||
// TODO Cleanup after ourselves..
|
// TODO Cleanup after ourselves..
|
||||||
|
|
||||||
|
@ -259,7 +261,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
|
||||||
assertEquals(newMetadataValue.getValue(), metadataValue.getValue());
|
assertEquals(newMetadataValue.getValue(), metadataValue.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(testName = "DELETE /vAppTemplate/{id}/metadata/{key}")
|
@Test(testName = "DELETE /vAppTemplate/{id}/metadata/{key}", dependsOnMethods = { "testGetMetadataValue" })
|
||||||
public void testDeleteVAppTemplateMetadataValue() {
|
public void testDeleteVAppTemplateMetadataValue() {
|
||||||
// First store a value
|
// First store a value
|
||||||
String key = name("key-");
|
String key = name("key-");
|
||||||
|
@ -379,7 +381,8 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
|
||||||
checkNetworkConnectionSection(modified);
|
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 {
|
public void testDeleteVAppTemplate() throws Exception {
|
||||||
VAppTemplate clonedVappTemplate = cloneVAppTemplate(true);
|
VAppTemplate clonedVappTemplate = cloneVAppTemplate(true);
|
||||||
|
|
||||||
|
@ -461,6 +464,13 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
|
||||||
assertTaskSucceedsLong(task);
|
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.
|
// This failed previously, but is passing now.
|
||||||
// However, it's not part of the official API so not necessary to assert it.
|
// However, it's not part of the official API so not necessary to assert it.
|
||||||
@Test(testName = "test completed task not included in vAppTemplate")
|
@Test(testName = "test completed task not included in vAppTemplate")
|
||||||
|
|
Loading…
Reference in New Issue