mirror of https://github.com/apache/jclouds.git
Merge pull request #509 from grkvlt/vapp-updates
Issue 830: Misc updates
This commit is contained in:
commit
6fda2580f5
|
@ -43,8 +43,10 @@
|
||||||
<test.vcloud-director.image.login-user></test.vcloud-director.image.login-user>
|
<test.vcloud-director.image.login-user></test.vcloud-director.image.login-user>
|
||||||
<test.vcloud-director.image.authenticate-sudo></test.vcloud-director.image.authenticate-sudo>
|
<test.vcloud-director.image.authenticate-sudo></test.vcloud-director.image.authenticate-sudo>
|
||||||
<test.vcloud-director.catalog-name>Public</test.vcloud-director.catalog-name>
|
<test.vcloud-director.catalog-name>Public</test.vcloud-director.catalog-name>
|
||||||
|
<test.vcloud-director.catalog-id></test.vcloud-director.catalog-id>
|
||||||
<test.vcloud-director.media-id></test.vcloud-director.media-id>
|
<test.vcloud-director.media-id></test.vcloud-director.media-id>
|
||||||
<test.vcloud-director.vapptemplate-id></test.vcloud-director.vapptemplate-id>
|
<test.vcloud-director.vapptemplate-id></test.vcloud-director.vapptemplate-id>
|
||||||
|
<test.vcloud-director.network-name></test.vcloud-director.network-name>
|
||||||
<test.vcloud-director.network-id></test.vcloud-director.network-id>
|
<test.vcloud-director.network-id></test.vcloud-director.network-id>
|
||||||
<test.vcloud-director.vdc-id></test.vcloud-director.vdc-id>
|
<test.vcloud-director.vdc-id></test.vcloud-director.vdc-id>
|
||||||
</properties>
|
</properties>
|
||||||
|
@ -114,9 +116,11 @@
|
||||||
<test.vcloud-director.image-id>${test.vcloud-director.image-id}</test.vcloud-director.image-id>
|
<test.vcloud-director.image-id>${test.vcloud-director.image-id}</test.vcloud-director.image-id>
|
||||||
<test.vcloud-director.image.login-user>${test.vcloud-director.image.login-user}</test.vcloud-director.image.login-user>
|
<test.vcloud-director.image.login-user>${test.vcloud-director.image.login-user}</test.vcloud-director.image.login-user>
|
||||||
<test.vcloud-director.image.authenticate-sudo>${test.vcloud-director.image.authenticate-sudo}</test.vcloud-director.image.authenticate-sudo>
|
<test.vcloud-director.image.authenticate-sudo>${test.vcloud-director.image.authenticate-sudo}</test.vcloud-director.image.authenticate-sudo>
|
||||||
|
<test.vcloud-director.catalog-id>${test.vcloud-director.catalog-id}</test.vcloud-director.catalog-id>
|
||||||
<test.vcloud-director.catalog-name>${test.vcloud-director.catalog-name}</test.vcloud-director.catalog-name>
|
<test.vcloud-director.catalog-name>${test.vcloud-director.catalog-name}</test.vcloud-director.catalog-name>
|
||||||
<test.vcloud-director.media-id>${test.vcloud-director.media-id}</test.vcloud-director.media-id>
|
<test.vcloud-director.media-id>${test.vcloud-director.media-id}</test.vcloud-director.media-id>
|
||||||
<test.vcloud-director.vapptemplate-id>${test.vcloud-director.vapptemplate-id}</test.vcloud-director.vapptemplate-id>
|
<test.vcloud-director.vapptemplate-id>${test.vcloud-director.vapptemplate-id}</test.vcloud-director.vapptemplate-id>
|
||||||
|
<test.vcloud-director.network-name>${test.vcloud-director.network-name}</test.vcloud-director.network-name>
|
||||||
<test.vcloud-director.network-id>${test.vcloud-director.network-id}</test.vcloud-director.network-id>
|
<test.vcloud-director.network-id>${test.vcloud-director.network-id}</test.vcloud-director.network-id>
|
||||||
<test.vcloud-director.vdc-id>${test.vcloud-director.vdc-id}</test.vcloud-director.vdc-id>
|
<test.vcloud-director.vdc-id>${test.vcloud-director.vdc-id}</test.vcloud-director.vdc-id>
|
||||||
</systemPropertyVariables>
|
</systemPropertyVariables>
|
||||||
|
|
|
@ -1,139 +0,0 @@
|
||||||
/**
|
|
||||||
* 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 static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
import javax.xml.bind.annotation.XmlType;
|
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a list of references to available networks.
|
|
||||||
* <p/>
|
|
||||||
* <p/>
|
|
||||||
* <p>Java class for AvailableNetworks complex type.
|
|
||||||
* <p/>
|
|
||||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
|
||||||
* <p/>
|
|
||||||
* <pre>
|
|
||||||
* <complexType name="AvailableNetworks">
|
|
||||||
* <complexContent>
|
|
||||||
* <extension base="{http://www.vmware.com/vcloud/v1.5}VCloudExtensibleType">
|
|
||||||
* <sequence>
|
|
||||||
* <element name="Network" type="{http://www.vmware.com/vcloud/v1.5}ReferenceType" maxOccurs="unbounded" minOccurs="0"/>
|
|
||||||
* </sequence>
|
|
||||||
* <anyAttribute processContents='lax' namespace='##other'/>
|
|
||||||
* </extension>
|
|
||||||
* </complexContent>
|
|
||||||
* </complexType>
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@XmlType(name = "AvailableNetworks", propOrder = {
|
|
||||||
"networks"
|
|
||||||
})
|
|
||||||
public class AvailableNetworks {
|
|
||||||
public static Builder builder() {
|
|
||||||
return new Builder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder toBuilder() {
|
|
||||||
return new Builder().fromAvailableNetworks(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder {
|
|
||||||
private Set<Reference> networks = Sets.newLinkedHashSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see AvailableNetworks#getNetworks()
|
|
||||||
*/
|
|
||||||
public Builder networks(Collection<Reference> networks) {
|
|
||||||
this.networks = Sets.newLinkedHashSet(checkNotNull(networks, "networks"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see AvailableNetworks#getNetworks()
|
|
||||||
*/
|
|
||||||
public Builder network(Reference network) {
|
|
||||||
networks.add(checkNotNull(network, "network"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AvailableNetworks build() {
|
|
||||||
AvailableNetworks availableNetworks = new AvailableNetworks(networks);
|
|
||||||
return availableNetworks;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Builder fromAvailableNetworks(AvailableNetworks in) {
|
|
||||||
return networks(in.getNetworks());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@XmlElement(name = "Network")
|
|
||||||
protected Set<Reference> networks = Sets.newLinkedHashSet();
|
|
||||||
|
|
||||||
private AvailableNetworks(Set<Reference> networks) {
|
|
||||||
this.networks = ImmutableSet.copyOf(networks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private AvailableNetworks() {
|
|
||||||
// For JAXB
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the value of the network property.
|
|
||||||
*/
|
|
||||||
public Set<Reference> getNetworks() {
|
|
||||||
return Collections.unmodifiableSet(this.networks);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (o == null || getClass() != o.getClass())
|
|
||||||
return false;
|
|
||||||
AvailableNetworks that = AvailableNetworks.class.cast(o);
|
|
||||||
return equal(networks, that.networks);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(networks);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return Objects.toStringHelper("")
|
|
||||||
.add("network", networks).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -20,11 +20,17 @@
|
||||||
package org.jclouds.vcloud.director.v1_5.domain;
|
package org.jclouds.vcloud.director.v1_5.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Objects.equal;
|
import static com.google.common.base.Objects.equal;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||||
import javax.xml.bind.annotation.XmlType;
|
import javax.xml.bind.annotation.XmlType;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,13 +68,21 @@ public class Capabilities {
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private SupportedHardwareVersions supportedHardwareVersions;
|
private Set<String> supportedHardwareVersions = Sets.newLinkedHashSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Capabilities#getSupportedHardwareVersions()
|
* @see Capabilities#getSupportedHardwareVersions()
|
||||||
*/
|
*/
|
||||||
public Builder supportedHardwareVersions(SupportedHardwareVersions supportedHardwareVersions) {
|
public Builder supportedHardwareVersions(Set<String> supportedHardwareVersions) {
|
||||||
this.supportedHardwareVersions = supportedHardwareVersions;
|
this.supportedHardwareVersions = Sets.newLinkedHashSet(checkNotNull(supportedHardwareVersions, "supportedHardwareVersions"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Capabilities#getSupportedHardwareVersions()
|
||||||
|
*/
|
||||||
|
public Builder supportedHardwareVersion(String supportedHardwareVersion) {
|
||||||
|
this.supportedHardwareVersions.add(checkNotNull(supportedHardwareVersion, "supportedHardwareVersion"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,12 +93,12 @@ public class Capabilities {
|
||||||
|
|
||||||
|
|
||||||
public Builder fromCapabilities(Capabilities in) {
|
public Builder fromCapabilities(Capabilities in) {
|
||||||
return supportedHardwareVersions(in.getSupportedHardwareVersions());
|
return supportedHardwareVersions(Sets.newLinkedHashSet(in.getSupportedHardwareVersions()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Capabilities(SupportedHardwareVersions supportedHardwareVersions) {
|
private Capabilities(Set<String> supportedHardwareVersions) {
|
||||||
this.supportedHardwareVersions = supportedHardwareVersions;
|
this.supportedHardwareVersions = supportedHardwareVersions == null ? Sets.<String>newLinkedHashSet() : ImmutableSet.copyOf(supportedHardwareVersions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Capabilities() {
|
private Capabilities() {
|
||||||
|
@ -92,16 +106,14 @@ public class Capabilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@XmlElement(name = "SupportedHardwareVersions")
|
@XmlElementWrapper(name = "SupportedHardwareVersions")
|
||||||
protected SupportedHardwareVersions supportedHardwareVersions;
|
@XmlElement(name = "SupportedHardwareVersion")
|
||||||
|
protected Set<String> supportedHardwareVersions = Sets.newLinkedHashSet();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of the supportedHardwareVersions property.
|
* Gets the value of the supportedHardwareVersions property.
|
||||||
*
|
|
||||||
* @return possible object is
|
|
||||||
* {@link SupportedHardwareVersions }
|
|
||||||
*/
|
*/
|
||||||
public SupportedHardwareVersions getSupportedHardwareVersions() {
|
public Set<String> getSupportedHardwareVersions() {
|
||||||
return supportedHardwareVersions;
|
return supportedHardwareVersions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import javax.xml.bind.annotation.XmlType;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic entity type in the vCloud object model.
|
* Basic entity type in the vCloud object model.
|
||||||
|
@ -104,7 +105,7 @@ public class EntityType extends ResourceType {
|
||||||
|
|
||||||
public B fromEntityType(EntityType in) {
|
public B fromEntityType(EntityType in) {
|
||||||
return fromResourceType(in)
|
return fromResourceType(in)
|
||||||
.description(in.getDescription()).tasks(in.getTasks())
|
.description(in.getDescription()).tasks(Sets.newLinkedHashSet(in.getTasks()))
|
||||||
.id(in.getId()).name(in.getName());
|
.id(in.getId()).name(in.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +124,7 @@ public class EntityType extends ResourceType {
|
||||||
super(builder);
|
super(builder);
|
||||||
this.description = builder.description;
|
this.description = builder.description;
|
||||||
// nullable so that jaxb wont persist empty collections
|
// nullable so that jaxb wont persist empty collections
|
||||||
this.tasks = builder.tasks != null && builder.tasks.size() == 0 ? null : builder.tasks;
|
this.tasks = builder.tasks == null || builder.tasks.isEmpty() ? null : ImmutableSet.copyOf(builder.tasks);
|
||||||
this.id = builder.id;
|
this.id = builder.id;
|
||||||
this.name = builder.name;
|
this.name = builder.name;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +148,7 @@ public class EntityType extends ResourceType {
|
||||||
* A list of queued, running, or recently completed tasks associated with this entity.
|
* A list of queued, running, or recently completed tasks associated with this entity.
|
||||||
*/
|
*/
|
||||||
public Set<Task> getTasks() {
|
public Set<Task> getTasks() {
|
||||||
return tasks == null ? ImmutableSet.<Task>of() : Collections.unmodifiableSet(tasks);
|
return tasks == null ? ImmutableSet.<Task>of() : ImmutableSet.copyOf(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
/**
|
|
||||||
* 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 static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
import javax.xml.bind.annotation.XmlType;
|
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a list of references to resource entities.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* <complexType name="ResourceEntities" />
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author grkvlt@apache.org
|
|
||||||
*/
|
|
||||||
@XmlType(name = "ResourceEntities")
|
|
||||||
public class ResourceEntities {
|
|
||||||
|
|
||||||
public static Builder builder() {
|
|
||||||
return new Builder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder toBuilder() {
|
|
||||||
return new Builder().fromResourceEntities(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder {
|
|
||||||
|
|
||||||
private Set<Reference> resourceEntities = Sets.newLinkedHashSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ResourceEntities#getResourceEntities()
|
|
||||||
*/
|
|
||||||
public Builder resourceEntities(Set<Reference> resourceEntities) {
|
|
||||||
this.resourceEntities = ImmutableSet.copyOf(checkNotNull(resourceEntities, "resourceEntities"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see ResourceEntities#getResourceEntities()
|
|
||||||
*/
|
|
||||||
public Builder resourceEntity(Reference resourceEntity) {
|
|
||||||
resourceEntities.add(checkNotNull(resourceEntity, "resourceEntity"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResourceEntities build() {
|
|
||||||
return new ResourceEntities(this.resourceEntities);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Builder fromResourceEntities(ResourceEntities in) {
|
|
||||||
return resourceEntities(in.getResourceEntities());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResourceEntities() {
|
|
||||||
// for JAXB
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResourceEntities(Set<Reference> resourceEntity) {
|
|
||||||
this.resourceEntities = ImmutableSet.copyOf(resourceEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@XmlElement(name = "ResourceEntity")
|
|
||||||
private Set<Reference> resourceEntities = Sets.newLinkedHashSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the value of the resourceEntity property.
|
|
||||||
*/
|
|
||||||
public Set<Reference> getResourceEntities() {
|
|
||||||
return Collections.unmodifiableSet(this.resourceEntities);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (o == null || getClass() != o.getClass())
|
|
||||||
return false;
|
|
||||||
ResourceEntities that = ResourceEntities.class.cast(o);
|
|
||||||
return equal(resourceEntities, that.resourceEntities);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(resourceEntities);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return Objects.toStringHelper("")
|
|
||||||
.add("resourceEntity", resourceEntities).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,140 +0,0 @@
|
||||||
/**
|
|
||||||
* 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 static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
|
||||||
import javax.xml.bind.annotation.XmlType;
|
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a list of supported VM hardware versions.
|
|
||||||
* <p/>
|
|
||||||
* <p/>
|
|
||||||
* <p>Java class for SupportedHardwareVersions complex type.
|
|
||||||
* <p/>
|
|
||||||
* <p>The following schema fragment specifies the expected content contained within this class.
|
|
||||||
* <p/>
|
|
||||||
* <pre>
|
|
||||||
* <complexType name="SupportedHardwareVersions">
|
|
||||||
* <complexContent>
|
|
||||||
* <extension base="{http://www.vmware.com/vcloud/v1.5}VCloudExtensibleType">
|
|
||||||
* <sequence>
|
|
||||||
* <element name="SupportedHardwareVersion" type="{http://www.vmware.com/vcloud/v1.5}SupportedHardwareVersionType" maxOccurs="unbounded" minOccurs="0"/>
|
|
||||||
* </sequence>
|
|
||||||
* <anyAttribute processContents='lax' namespace='##other'/>
|
|
||||||
* </extension>
|
|
||||||
* </complexContent>
|
|
||||||
* </complexType>
|
|
||||||
* </pre>
|
|
||||||
*/
|
|
||||||
@XmlType(name = "SupportedHardwareVersions", propOrder = {
|
|
||||||
"supportedHardwareVersions"
|
|
||||||
})
|
|
||||||
public class SupportedHardwareVersions {
|
|
||||||
public static Builder builder() {
|
|
||||||
return new Builder();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder toBuilder() {
|
|
||||||
return new Builder().fromSupportedHardwareVersions(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder {
|
|
||||||
|
|
||||||
private Set<String> supportedHardwareVersions = Sets.newLinkedHashSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see SupportedHardwareVersions#getSupportedHardwareVersions()
|
|
||||||
*/
|
|
||||||
public Builder supportedHardwareVersions(Set<String> supportedHardwareVersions) {
|
|
||||||
this.supportedHardwareVersions = Sets.newLinkedHashSet(checkNotNull(supportedHardwareVersions, "supportedHardwareVersions"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see SupportedHardwareVersions#getSupportedHardwareVersions()
|
|
||||||
*/
|
|
||||||
public Builder supportedHardwareVersion(String supportedHardwareVersion) {
|
|
||||||
supportedHardwareVersions.add(checkNotNull(supportedHardwareVersion, "supportedHardwareVersion"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SupportedHardwareVersions build() {
|
|
||||||
SupportedHardwareVersions supportedHardwareVersions = new SupportedHardwareVersions(this.supportedHardwareVersions);
|
|
||||||
return supportedHardwareVersions;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Builder fromSupportedHardwareVersions(SupportedHardwareVersions in) {
|
|
||||||
return supportedHardwareVersions(in.getSupportedHardwareVersions());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private SupportedHardwareVersions() {
|
|
||||||
// for JAXB
|
|
||||||
}
|
|
||||||
|
|
||||||
private SupportedHardwareVersions(Set<String> supportedHardwareVersions) {
|
|
||||||
this.supportedHardwareVersions = ImmutableSet.copyOf(supportedHardwareVersions);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@XmlElement(name = "SupportedHardwareVersion")
|
|
||||||
protected Set<String> supportedHardwareVersions = Sets.newLinkedHashSet();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the value of the supportedHardwareVersion property.
|
|
||||||
*/
|
|
||||||
public Set<String> getSupportedHardwareVersions() {
|
|
||||||
return Collections.unmodifiableSet(supportedHardwareVersions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o)
|
|
||||||
return true;
|
|
||||||
if (o == null || getClass() != o.getClass())
|
|
||||||
return false;
|
|
||||||
SupportedHardwareVersions that = SupportedHardwareVersions.class.cast(o);
|
|
||||||
return equal(supportedHardwareVersions, that.supportedHardwareVersions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hashCode(supportedHardwareVersions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return Objects.toStringHelper("")
|
|
||||||
.add("supportedHardwareVersion", supportedHardwareVersions).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -19,15 +19,21 @@
|
||||||
package org.jclouds.vcloud.director.v1_5.domain;
|
package org.jclouds.vcloud.director.v1_5.domain;
|
||||||
|
|
||||||
import static com.google.common.base.Objects.equal;
|
import static com.google.common.base.Objects.equal;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAttribute;
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||||
import javax.xml.bind.annotation.XmlType;
|
import javax.xml.bind.annotation.XmlType;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a virtual data center (vDC).
|
* Represents a virtual data center (vDC).
|
||||||
|
@ -45,6 +51,7 @@ public class Vdc extends EntityType {
|
||||||
return new ConcreteBuilder();
|
return new ConcreteBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Builder<?> toBuilder() {
|
public Builder<?> toBuilder() {
|
||||||
return builder().fromVdc(this);
|
return builder().fromVdc(this);
|
||||||
}
|
}
|
||||||
|
@ -56,8 +63,8 @@ public class Vdc extends EntityType {
|
||||||
private String allocationModel;
|
private String allocationModel;
|
||||||
private CapacityWithUsage storageCapacity;
|
private CapacityWithUsage storageCapacity;
|
||||||
private ComputeCapacity computeCapacity;
|
private ComputeCapacity computeCapacity;
|
||||||
private ResourceEntities resourceEntities;
|
private Set<Reference> resourceEntities = Sets.newLinkedHashSet();
|
||||||
private AvailableNetworks availableNetworks;
|
private Set<Reference> availableNetworks = Sets.newLinkedHashSet();
|
||||||
private Capabilities capabilities;
|
private Capabilities capabilities;
|
||||||
private Integer nicQuota;
|
private Integer nicQuota;
|
||||||
private Integer networkQuota;
|
private Integer networkQuota;
|
||||||
|
@ -92,16 +99,32 @@ public class Vdc extends EntityType {
|
||||||
/**
|
/**
|
||||||
* @see Vdc#getResourceEntities()
|
* @see Vdc#getResourceEntities()
|
||||||
*/
|
*/
|
||||||
public B resourceEntities(ResourceEntities resourceEntities) {
|
public B resourceEntities(Set<Reference> resourceEntities) {
|
||||||
this.resourceEntities = resourceEntities;
|
this.resourceEntities = Sets.newLinkedHashSet(checkNotNull(resourceEntities, "resourceEntities"));
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Vdc#getResourceEntities()
|
||||||
|
*/
|
||||||
|
public B resourceEntity(Reference resourceEntity) {
|
||||||
|
this.resourceEntities.add(checkNotNull(resourceEntity, "resourceEntity"));
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Vdc#getAvailableNetworks()
|
* @see Vdc#getAvailableNetworks()
|
||||||
*/
|
*/
|
||||||
public B availableNetworks(AvailableNetworks availableNetworks) {
|
public B availableNetworks(Set<Reference> availableNetworks) {
|
||||||
this.availableNetworks = availableNetworks;
|
this.availableNetworks = Sets.newLinkedHashSet(checkNotNull(availableNetworks, "availableNetworks"));
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Vdc#getAvailableNetworks()
|
||||||
|
*/
|
||||||
|
public B network(Reference availableNetwork) {
|
||||||
|
this.availableNetworks.add(checkNotNull(availableNetwork, "availableNetwork"));;
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +186,8 @@ public class Vdc extends EntityType {
|
||||||
.allocationModel(in.getAllocationModel())
|
.allocationModel(in.getAllocationModel())
|
||||||
.storageCapacity(in.getStorageCapacity())
|
.storageCapacity(in.getStorageCapacity())
|
||||||
.computeCapacity(in.getComputeCapacity())
|
.computeCapacity(in.getComputeCapacity())
|
||||||
.resourceEntities(in.getResourceEntities())
|
.resourceEntities(Sets.newLinkedHashSet(in.getResourceEntities()))
|
||||||
.availableNetworks(in.getAvailableNetworks())
|
.availableNetworks(Sets.newLinkedHashSet(in.getAvailableNetworks()))
|
||||||
.capabilities(in.getCapabilities())
|
.capabilities(in.getCapabilities())
|
||||||
.nicQuota(in.getNicQuota())
|
.nicQuota(in.getNicQuota())
|
||||||
.networkQuota(in.getNetworkQuota())
|
.networkQuota(in.getNetworkQuota())
|
||||||
|
@ -183,8 +206,8 @@ public class Vdc extends EntityType {
|
||||||
this.allocationModel = builder.allocationModel;
|
this.allocationModel = builder.allocationModel;
|
||||||
this.storageCapacity = builder.storageCapacity;
|
this.storageCapacity = builder.storageCapacity;
|
||||||
this.computeCapacity = builder.computeCapacity;
|
this.computeCapacity = builder.computeCapacity;
|
||||||
this.resourceEntities = builder.resourceEntities;
|
this.resourceEntities = builder.resourceEntities == null ? Sets.<Reference>newLinkedHashSet() : ImmutableSet.copyOf(builder.resourceEntities);
|
||||||
this.availableNetworks = builder.availableNetworks;
|
this.availableNetworks = builder.availableNetworks == null ? Sets.<Reference>newLinkedHashSet() : ImmutableSet.copyOf(builder.availableNetworks);
|
||||||
this.capabilities = builder.capabilities;
|
this.capabilities = builder.capabilities;
|
||||||
this.nicQuota = builder.nicQuota;
|
this.nicQuota = builder.nicQuota;
|
||||||
this.networkQuota = builder.networkQuota;
|
this.networkQuota = builder.networkQuota;
|
||||||
|
@ -199,10 +222,12 @@ public class Vdc extends EntityType {
|
||||||
private CapacityWithUsage storageCapacity;
|
private CapacityWithUsage storageCapacity;
|
||||||
@XmlElement(name = "ComputeCapacity", required = true)
|
@XmlElement(name = "ComputeCapacity", required = true)
|
||||||
private ComputeCapacity computeCapacity;
|
private ComputeCapacity computeCapacity;
|
||||||
@XmlElement(name = "ResourceEntities")
|
@XmlElementWrapper(name = "ResourceEntities")
|
||||||
private ResourceEntities resourceEntities;
|
@XmlElement(name = "ResourceEntity")
|
||||||
@XmlElement(name = "AvailableNetworks")
|
private Set<Reference> resourceEntities = Sets.newLinkedHashSet();
|
||||||
private AvailableNetworks availableNetworks;
|
@XmlElementWrapper(name = "AvailableNetworks")
|
||||||
|
@XmlElement(name = "Network")
|
||||||
|
protected Set<Reference> availableNetworks = Sets.newLinkedHashSet();
|
||||||
@XmlElement(name = "Capabilities")
|
@XmlElement(name = "Capabilities")
|
||||||
private Capabilities capabilities;
|
private Capabilities capabilities;
|
||||||
@XmlElement(name = "NicQuota")
|
@XmlElement(name = "NicQuota")
|
||||||
|
@ -240,14 +265,14 @@ public class Vdc extends EntityType {
|
||||||
/**
|
/**
|
||||||
* Gets the value of the resourceEntities property.
|
* Gets the value of the resourceEntities property.
|
||||||
*/
|
*/
|
||||||
public ResourceEntities getResourceEntities() {
|
public Set<Reference> getResourceEntities() {
|
||||||
return resourceEntities;
|
return resourceEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of the availableNetworks property.
|
* Gets the value of the availableNetworks property.
|
||||||
*/
|
*/
|
||||||
public AvailableNetworks getAvailableNetworks() {
|
public Set<Reference> getAvailableNetworks() {
|
||||||
return availableNetworks;
|
return availableNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,18 +78,20 @@ public interface OrgAsyncClient {
|
||||||
@Consumes(CONTROL_ACCESS)
|
@Consumes(CONTROL_ACCESS)
|
||||||
@JAXBResponseParser
|
@JAXBResponseParser
|
||||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||||
ListenableFuture<ControlAccessParams> modifyControlAccess(@EndpointParam URI orgURI, @PathParam("catalogId") String catalogId,
|
ListenableFuture<ControlAccessParams> modifyControlAccess(@EndpointParam URI orgRef,
|
||||||
|
@PathParam("catalogId") String catalogId,
|
||||||
@BinderParam(BindToXMLPayload.class) ControlAccessParams params);
|
@BinderParam(BindToXMLPayload.class) ControlAccessParams params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see OrgClient#getControlAccess(URI, URI, ControlAccessParams)
|
* @see OrgClient#getControlAccess(URI, URI, ControlAccessParams)
|
||||||
*/
|
*/
|
||||||
@POST
|
@GET
|
||||||
@Path("/catalog/{catalogId}/controlAccess")
|
@Path("/catalog/{catalogId}/controlAccess")
|
||||||
@Consumes
|
@Consumes
|
||||||
@JAXBResponseParser
|
@JAXBResponseParser
|
||||||
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
@ExceptionParser(ThrowVCloudErrorOn4xx.class)
|
||||||
ListenableFuture<ControlAccessParams> getControlAccess(@EndpointParam URI orgURI, @PathParam("catalogId") String catalogId);
|
ListenableFuture<ControlAccessParams> getControlAccess(@EndpointParam URI orgRef,
|
||||||
|
@PathParam("catalogId") String catalogId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return asynchronous access to {@link Metadata.Readable} features
|
* @return asynchronous access to {@link Metadata.Readable} features
|
||||||
|
|
|
@ -520,27 +520,10 @@ public class Checks {
|
||||||
assertTrue(capacity.getAllocated() >= 0, "allocated must be greater than or equal to 0");
|
assertTrue(capacity.getAllocated() >= 0, "allocated must be greater than or equal to 0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void checkResourceEntities(ResourceEntities resourceEntities) {
|
|
||||||
for (Reference resourceEntity : resourceEntities.getResourceEntities()) {
|
|
||||||
checkReferenceType(resourceEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void checkAvailableNetworks(AvailableNetworks availableNetworks) {
|
|
||||||
for (Reference network : availableNetworks.getNetworks()) {
|
|
||||||
checkReferenceType(network);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void checkCapabilities(Capabilities capabilities) {
|
public static void checkCapabilities(Capabilities capabilities) {
|
||||||
// Check optional fields
|
// Check optional fields
|
||||||
if (capabilities.getSupportedHardwareVersions() != null) {
|
for (String supportedHardwareVersion : capabilities.getSupportedHardwareVersions()) {
|
||||||
checkSupportedHardwareVersions(capabilities.getSupportedHardwareVersions());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static void checkSupportedHardwareVersions(SupportedHardwareVersions supportedHardwareVersions) {
|
|
||||||
for (String supportedHardwareVersion : supportedHardwareVersions.getSupportedHardwareVersions()) {
|
|
||||||
// NOTE supportedHardwareVersion cannot be checked?
|
// NOTE supportedHardwareVersion cannot be checked?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1469,11 +1452,11 @@ public class Checks {
|
||||||
|
|
||||||
// optional
|
// optional
|
||||||
// NOTE isEnabled cannot be checked
|
// NOTE isEnabled cannot be checked
|
||||||
if (vdc.getResourceEntities() != null) {
|
for (Reference resourceEntity : vdc.getResourceEntities()) {
|
||||||
checkResourceEntities(vdc.getResourceEntities());
|
checkReferenceType(resourceEntity);
|
||||||
}
|
}
|
||||||
if (vdc.getAvailableNetworks() != null) {
|
for (Reference availableNetwork : vdc.getAvailableNetworks()) {
|
||||||
checkAvailableNetworks(vdc.getAvailableNetworks());
|
checkReferenceType(availableNetwork);
|
||||||
}
|
}
|
||||||
if (vdc.getCapabilities() != null) {
|
if (vdc.getCapabilities() != null) {
|
||||||
checkCapabilities(vdc.getCapabilities());
|
checkCapabilities(vdc.getCapabilities());
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.GuestCustomizationSection;
|
import org.jclouds.vcloud.director.v1_5.domain.GuestCustomizationSection;
|
||||||
|
@ -54,6 +55,7 @@ import org.jclouds.vcloud.director.v1_5.predicates.ReferenceTypePredicates;
|
||||||
import org.jclouds.xml.internal.JAXBParser;
|
import org.jclouds.xml.internal.JAXBParser;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.AfterClass;
|
import org.testng.annotations.AfterClass;
|
||||||
|
import org.testng.annotations.AfterTest;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -179,21 +181,23 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
|
||||||
|
|
||||||
@AfterClass(alwaysRun = true, description = "Cleans up the environment by deleting created VApps")
|
@AfterClass(alwaysRun = true, description = "Cleans up the environment by deleting created VApps")
|
||||||
protected void cleanUp() {
|
protected void cleanUp() {
|
||||||
// Find references in the Vdc with the VApp type and named 'test-vapp' or 'new-name'
|
vdc = vdcClient.getVdc(vdcURI); // Refresh
|
||||||
|
// Find references in the Vdc with the VApp type and in the list of instantiated VApp names
|
||||||
Iterable<Reference> vApps = Iterables.filter(
|
Iterable<Reference> vApps = Iterables.filter(
|
||||||
vdc.getResourceEntities().getResourceEntities(),
|
vdc.getResourceEntities(),
|
||||||
Predicates.and(
|
Predicates.and(
|
||||||
ReferenceTypePredicates.<Reference>typeEquals(VCloudDirectorMediaType.VAPP),
|
ReferenceTypePredicates.<Reference>typeEquals(VCloudDirectorMediaType.VAPP),
|
||||||
ReferenceTypePredicates.<Reference>nameIn(vAppNames)
|
ReferenceTypePredicates.<Reference>nameIn(vAppNames)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
vAppNames.clear();
|
|
||||||
|
|
||||||
// If we found any references, delete the VApp they point to
|
// If we found any references, delete the VApp they point to
|
||||||
if (vApps != null && !Iterables.isEmpty(vApps)) {
|
if (!Iterables.isEmpty(vApps)) {
|
||||||
for (Reference ref : vApps) {
|
for (Reference ref : vApps) {
|
||||||
cleanUpVApp(ref.getHref()); // NOTE may fail, but should continue deleting
|
cleanUpVApp(ref.getHref()); // NOTE may fail, but should continue deleting
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn("No VApps in list found in Vdc %s (%s)", vdc.getName(), Iterables.toString(vAppNames));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,16 +322,18 @@ public abstract class AbstractVAppClientLiveTest extends BaseVCloudDirectorClien
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marshals a JAXB annotated object into XML. The XML is output on {@link System#err}.
|
* Marshals a JAXB annotated object into XML.
|
||||||
|
*
|
||||||
|
* The XML is output using {@link org.jclouds.logging.Logger#debug(String)}
|
||||||
*/
|
*/
|
||||||
protected void debug(Object object) {
|
protected void debug(Object object) {
|
||||||
JAXBParser parser = new JAXBParser();
|
JAXBParser parser = new JAXBParser();
|
||||||
try {
|
try {
|
||||||
String xml = parser.toXML(object);
|
String xml = parser.toXML(object);
|
||||||
|
|
||||||
System.err.println(Strings.padStart(Strings.padEnd(" " + object.getClass().toString() + " ", 70, '-'), 80, '-'));
|
logger.debug(Strings.padStart(Strings.padEnd(" " + object.getClass().toString() + " ", 70, '-'), 80, '-'));
|
||||||
System.err.println(xml);
|
logger.debug(xml);
|
||||||
System.err.println(Strings.repeat("-", 80));
|
logger.debug(Strings.repeat("-", 80));
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Throwables.propagate(ioe);
|
Throwables.propagate(ioe);
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,18 +145,24 @@ public class OrgClientLiveTest extends BaseVCloudDirectorClientLiveTest {
|
||||||
assertEquals(value.getValue(), expected, String.format(CORRECT_VALUE_OBJECT_FMT, "Value", "MetadataValue", expected, value.getValue()));
|
assertEquals(value.getValue(), expected, String.format(CORRECT_VALUE_OBJECT_FMT, "Value", "MetadataValue", expected, value.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(testName = "GET /org/{id}/catalog/{catalogId}/controlAccess")
|
@Test(testName = "GET /org/{id}/catalog/{catalogId}/controlAccess", dependsOnMethods = { "testGetOrg" })
|
||||||
public void testGetontrolAccess() {
|
public void testGetControlAccess() {
|
||||||
String catalogId = "";
|
// Call the method being tested
|
||||||
ControlAccessParams params = orgClient.getControlAccess(orgURI, catalogId);
|
ControlAccessParams params = orgClient.getControlAccess(orgURI, catalogId);
|
||||||
|
|
||||||
|
// Check params are well formed
|
||||||
checkControlAccessParams(params);
|
checkControlAccessParams(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(testName = "GET /org/{id}/catalog/{catalogId}/action/controlAccess", dependsOnMethods = { "testGetontrolAccess" })
|
@Test(testName = "GET /org/{id}/catalog/{catalogId}/action/controlAccess", dependsOnMethods = { "testGetControlAccess" })
|
||||||
public void testModifyControlAccess() {
|
public void testModifyControlAccess() {
|
||||||
String catalogId = "";
|
// Setup params
|
||||||
ControlAccessParams params = orgClient.getControlAccess(orgURI, catalogId);
|
ControlAccessParams params = orgClient.getControlAccess(orgURI, catalogId);
|
||||||
|
|
||||||
|
// Call the method being tested
|
||||||
ControlAccessParams modified = orgClient.modifyControlAccess(orgURI, catalogId, params);
|
ControlAccessParams modified = orgClient.modifyControlAccess(orgURI, catalogId, params);
|
||||||
|
|
||||||
|
// Check params are well formed
|
||||||
checkControlAccessParams(modified);
|
checkControlAccessParams(modified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -635,7 +635,7 @@ public class VAppClientLiveTest extends AbstractVAppClientLiveTest {
|
||||||
@Test(testName = "PUT /vApp/{id}/networkConnectionSection", dependsOnMethods = { "testGetNetworkConnectionSection" })
|
@Test(testName = "PUT /vApp/{id}/networkConnectionSection", dependsOnMethods = { "testGetNetworkConnectionSection" })
|
||||||
public void testModifyNetworkConnectionSection() {
|
public void testModifyNetworkConnectionSection() {
|
||||||
// Look up a network in the Vdc
|
// Look up a network in the Vdc
|
||||||
Set<Reference> networks = vdc.getAvailableNetworks().getNetworks();
|
Set<Reference> networks = vdc.getAvailableNetworks();
|
||||||
Reference network = Iterables.getLast(networks);
|
Reference network = Iterables.getLast(networks);
|
||||||
|
|
||||||
// Copy existing section and update fields
|
// Copy existing section and update fields
|
||||||
|
|
|
@ -371,7 +371,7 @@ public class VAppTemplateClientLiveTest extends AbstractVAppClientLiveTest {
|
||||||
@Test(testName = "PUT /vAppTemplate/{id}/networkConnectionSection")
|
@Test(testName = "PUT /vAppTemplate/{id}/networkConnectionSection")
|
||||||
public void testEditNetworkConnectionSection() {
|
public void testEditNetworkConnectionSection() {
|
||||||
// Look up a network in the Vdc
|
// Look up a network in the Vdc
|
||||||
Set<Reference> networks = vdc.getAvailableNetworks().getNetworks();
|
Set<Reference> networks = vdc.getAvailableNetworks();
|
||||||
Reference network = Iterables.getLast(networks);
|
Reference network = Iterables.getLast(networks);
|
||||||
|
|
||||||
// Copy existing section and update fields
|
// Copy existing section and update fields
|
||||||
|
|
|
@ -18,14 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.vcloud.director.v1_5.features;
|
package org.jclouds.vcloud.director.v1_5.features;
|
||||||
|
|
||||||
import static org.testng.Assert.*;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.fail;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorClient;
|
import org.jclouds.vcloud.director.v1_5.VCloudDirectorClient;
|
||||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorException;
|
import org.jclouds.vcloud.director.v1_5.VCloudDirectorException;
|
||||||
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.AvailableNetworks;
|
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.Capabilities;
|
import org.jclouds.vcloud.director.v1_5.domain.Capabilities;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.CapacityWithUsage;
|
import org.jclouds.vcloud.director.v1_5.domain.CapacityWithUsage;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.CaptureVAppParams;
|
import org.jclouds.vcloud.director.v1_5.domain.CaptureVAppParams;
|
||||||
|
@ -41,8 +41,6 @@ import org.jclouds.vcloud.director.v1_5.domain.Media;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.Metadata;
|
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.MetadataValue;
|
||||||
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.ResourceEntities;
|
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.SupportedHardwareVersions;
|
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.UploadVAppTemplateParams;
|
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.VApp;
|
||||||
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
|
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
|
||||||
|
@ -467,47 +465,41 @@ public class VdcClientExpectTest extends BaseVCloudDirectorRestClientExpectTest
|
||||||
.overhead(0l)
|
.overhead(0l)
|
||||||
.build())
|
.build())
|
||||||
.build())
|
.build())
|
||||||
.resourceEntities(ResourceEntities.builder()
|
.resourceEntity(Reference.builder()
|
||||||
.resourceEntity(Reference.builder()
|
|
||||||
.type("application/vnd.vmware.vcloud.vApp+xml")
|
.type("application/vnd.vmware.vcloud.vApp+xml")
|
||||||
.name("vcdcap-db9")
|
.name("vcdcap-db9")
|
||||||
.href(URI.create("https://mycloud.greenhousedata.com/api/vApp/vapp-e2a4ab74-ea62-4afa-8bb7-0c11259044fb"))
|
.href(URI.create("https://mycloud.greenhousedata.com/api/vApp/vapp-e2a4ab74-ea62-4afa-8bb7-0c11259044fb"))
|
||||||
.build())
|
.build())
|
||||||
.resourceEntity(Reference.builder()
|
.resourceEntity(Reference.builder()
|
||||||
.type("application/vnd.vmware.vcloud.vAppTemplate+xml")
|
.type("application/vnd.vmware.vcloud.vAppTemplate+xml")
|
||||||
.name("adriancolecap")
|
.name("adriancolecap")
|
||||||
.href(URI.create("https://mycloud.greenhousedata.com/api/vAppTemplate/vappTemplate-5571eb21-f532-4506-9737-01a4635a04cb"))
|
.href(URI.create("https://mycloud.greenhousedata.com/api/vAppTemplate/vappTemplate-5571eb21-f532-4506-9737-01a4635a04cb"))
|
||||||
.build())
|
.build())
|
||||||
.resourceEntity(Reference.builder()
|
.resourceEntity(Reference.builder()
|
||||||
.type("application/vnd.vmware.vcloud.media+xml")
|
.type("application/vnd.vmware.vcloud.media+xml")
|
||||||
.name("DansTestMedia")
|
.name("DansTestMedia")
|
||||||
.href(URI.create("https://mycloud.greenhousedata.com/api/media/794eb334-754e-4917-b5a0-5df85cbd61d1"))
|
.href(URI.create("https://mycloud.greenhousedata.com/api/media/794eb334-754e-4917-b5a0-5df85cbd61d1"))
|
||||||
.build())
|
.build())
|
||||||
.build())
|
.network(Reference.builder()
|
||||||
.availableNetworks(AvailableNetworks.builder()
|
|
||||||
.network(Reference.builder()
|
|
||||||
.type("application/vnd.vmware.vcloud.network+xml")
|
.type("application/vnd.vmware.vcloud.network+xml")
|
||||||
.name("orgNet-cloudsoft-Isolated")
|
.name("orgNet-cloudsoft-Isolated")
|
||||||
.href(URI.create("https://mycloud.greenhousedata.com/api/network/a604f3c2-0343-453e-ae1f-cddac5b7bd94"))
|
.href(URI.create("https://mycloud.greenhousedata.com/api/network/a604f3c2-0343-453e-ae1f-cddac5b7bd94"))
|
||||||
.build())
|
.build())
|
||||||
.network(Reference.builder()
|
.network(Reference.builder()
|
||||||
.type("application/vnd.vmware.vcloud.network+xml")
|
.type("application/vnd.vmware.vcloud.network+xml")
|
||||||
.name("orgNet-cloudsoft-External")
|
.name("orgNet-cloudsoft-External")
|
||||||
.href(URI.create("https://mycloud.greenhousedata.com/api/network/b466c0c5-8a5c-4335-b703-a2e2e6b5f3e1"))
|
.href(URI.create("https://mycloud.greenhousedata.com/api/network/b466c0c5-8a5c-4335-b703-a2e2e6b5f3e1"))
|
||||||
.build())
|
.build())
|
||||||
.network(Reference.builder()
|
.network(Reference.builder()
|
||||||
.type("application/vnd.vmware.vcloud.network+xml")
|
.type("application/vnd.vmware.vcloud.network+xml")
|
||||||
.name("orgNet-cloudsoft-Internal-Routed")
|
.name("orgNet-cloudsoft-Internal-Routed")
|
||||||
.href(URI.create("https://mycloud.greenhousedata.com/api/network/6d7392e2-c816-43fb-99be-f9ebcd70abf6"))
|
.href(URI.create("https://mycloud.greenhousedata.com/api/network/6d7392e2-c816-43fb-99be-f9ebcd70abf6"))
|
||||||
.build())
|
.build())
|
||||||
.build())
|
|
||||||
.capabilities(Capabilities.builder()
|
.capabilities(Capabilities.builder()
|
||||||
.supportedHardwareVersions(SupportedHardwareVersions.builder()
|
|
||||||
.supportedHardwareVersion("vmx-04")
|
.supportedHardwareVersion("vmx-04")
|
||||||
.supportedHardwareVersion("vmx-07")
|
.supportedHardwareVersion("vmx-07")
|
||||||
.supportedHardwareVersion("vmx-08")
|
.supportedHardwareVersion("vmx-08")
|
||||||
.build())
|
.build())
|
||||||
.build())
|
|
||||||
.nicQuota(0)
|
.nicQuota(0)
|
||||||
.networkQuota(10)
|
.networkQuota(10)
|
||||||
.vmQuota(10)
|
.vmQuota(10)
|
||||||
|
|
|
@ -228,7 +228,7 @@ public class VdcClientLiveTest extends BaseVCloudDirectorClientLiveTest {
|
||||||
public void testInstantiateVAppTemplate() {
|
public void testInstantiateVAppTemplate() {
|
||||||
Vdc vdc = vdcClient.getVdc(vdcURI);
|
Vdc vdc = vdcClient.getVdc(vdcURI);
|
||||||
|
|
||||||
Set<Reference> networks = vdc.getAvailableNetworks().getNetworks();
|
Set<Reference> networks = vdc.getAvailableNetworks();
|
||||||
Optional<Reference> parentNetwork = Iterables.tryFind(
|
Optional<Reference> parentNetwork = Iterables.tryFind(
|
||||||
networks, new Predicate<Reference>() {
|
networks, new Predicate<Reference>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -77,6 +77,7 @@ import org.testng.annotations.Test;
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
@ -96,7 +97,7 @@ import com.google.inject.Module;
|
||||||
public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServiceLiveTest {
|
public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServiceLiveTest {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.CONSOLE;
|
||||||
|
|
||||||
protected static final long TASK_TIMEOUT_SECONDS = 100L;
|
protected static final long TASK_TIMEOUT_SECONDS = 100L;
|
||||||
protected static final long LONG_TASK_TIMEOUT_SECONDS = 300L;
|
protected static final long LONG_TASK_TIMEOUT_SECONDS = 300L;
|
||||||
|
@ -112,6 +113,7 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ
|
||||||
protected Session session;
|
protected Session session;
|
||||||
|
|
||||||
protected String catalogName;
|
protected String catalogName;
|
||||||
|
protected String catalogId;
|
||||||
protected String networkName;
|
protected String networkName;
|
||||||
protected String userName;
|
protected String userName;
|
||||||
|
|
||||||
|
@ -166,6 +168,7 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected void initTestParametersFromPropertiesOrLazyDiscover() {
|
protected void initTestParametersFromPropertiesOrLazyDiscover() {
|
||||||
catalogName = Strings.emptyToNull(System.getProperty("test." + provider + ".catalog-name"));
|
catalogName = Strings.emptyToNull(System.getProperty("test." + provider + ".catalog-name"));
|
||||||
|
catalogId = Strings.emptyToNull(System.getProperty("test." + provider + ".catalog-id"));
|
||||||
networkName = Strings.emptyToNull(System.getProperty("test." + provider + ".network-name"));
|
networkName = Strings.emptyToNull(System.getProperty("test." + provider + ".network-name"));
|
||||||
|
|
||||||
String vAppTemplateId = Strings.emptyToNull(System.getProperty("test." + provider + ".vapptemplate-id"));
|
String vAppTemplateId = Strings.emptyToNull(System.getProperty("test." + provider + ".vapptemplate-id"));
|
||||||
|
@ -201,11 +204,20 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ
|
||||||
networkURI = Iterables.find(thisOrg.getLinks(),
|
networkURI = Iterables.find(thisOrg.getLinks(),
|
||||||
ReferenceTypePredicates.<Link> typeEquals(VCloudDirectorMediaType.ORG_NETWORK)).getHref();
|
ReferenceTypePredicates.<Link> typeEquals(VCloudDirectorMediaType.ORG_NETWORK)).getHref();
|
||||||
|
|
||||||
if (catalogName == null)
|
if (Strings.isNullOrEmpty(networkName))
|
||||||
|
networkName = Iterables.find(thisOrg.getLinks(),
|
||||||
|
ReferenceTypePredicates.<Link> typeEquals(VCloudDirectorMediaType.ORG_NETWORK)).getName();
|
||||||
|
|
||||||
|
if (Strings.isNullOrEmpty(catalogName))
|
||||||
catalogName = Iterables.find(thisOrg.getLinks(),
|
catalogName = Iterables.find(thisOrg.getLinks(),
|
||||||
ReferenceTypePredicates.<Link> typeEquals(VCloudDirectorMediaType.CATALOG)).getName();
|
ReferenceTypePredicates.<Link> typeEquals(VCloudDirectorMediaType.CATALOG)).getName();
|
||||||
|
|
||||||
// TODO look for default networkName
|
// FIXME the URI should be opaque
|
||||||
|
if (Strings.isNullOrEmpty(catalogId)) {
|
||||||
|
String uri = Iterables.find(thisOrg.getLinks(),
|
||||||
|
ReferenceTypePredicates.<Link> typeEquals(VCloudDirectorMediaType.CATALOG)).getHref().toASCIIString();
|
||||||
|
catalogId = Iterables.getLast(Splitter.on('/').split(uri));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +320,7 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ
|
||||||
Vdc vdc = context.getApi().getVdcClient().getVdc(vdcURI);
|
Vdc vdc = context.getApi().getVdcClient().getVdc(vdcURI);
|
||||||
assertNotNull(vdc, String.format(ENTITY_NON_NULL, VDC));
|
assertNotNull(vdc, String.format(ENTITY_NON_NULL, VDC));
|
||||||
|
|
||||||
Set<Reference> networks = vdc.getAvailableNetworks().getNetworks();
|
Set<Reference> networks = vdc.getAvailableNetworks();
|
||||||
|
|
||||||
// Look up the network in the Vdc with the id configured for the tests
|
// Look up the network in the Vdc with the id configured for the tests
|
||||||
Optional<Reference> parentNetwork = Iterables.tryFind(networks, new Predicate<Reference>() {
|
Optional<Reference> parentNetwork = Iterables.tryFind(networks, new Predicate<Reference>() {
|
||||||
|
@ -344,14 +356,16 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO code tidy for cleanUpVApp? Seems extremely verbose!
|
// TODO code tidy for cleanUpVApp? Seems extremely verbose!
|
||||||
protected void cleanUpVApp(URI vAppUri) {
|
protected void cleanUpVApp(URI vAppURI) {
|
||||||
VAppClient vappClient = context.getApi().getVAppClient();
|
VAppClient vAppClient = context.getApi().getVAppClient();
|
||||||
|
|
||||||
VApp vApp;
|
VApp vApp;
|
||||||
try {
|
try {
|
||||||
vApp = vappClient.getVApp(vAppUri); // update
|
vApp = vAppClient.getVApp(vAppURI); // Refresh
|
||||||
|
logger.debug("Deleting VApp %s (%s)", vApp.getName(), vAppURI.getPath());
|
||||||
} catch (VCloudDirectorException e) {
|
} catch (VCloudDirectorException e) {
|
||||||
// presumably vApp has already been deleted; ignore
|
// Presumably vApp has already been deleted. Ignore.
|
||||||
|
logger.info("Cannot find VApp at %s", vAppURI.getPath());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,11 +380,11 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ
|
||||||
// Shutdown and power off the VApp if necessary
|
// Shutdown and power off the VApp if necessary
|
||||||
if (vApp.getStatus().equals(Status.POWERED_ON.getValue())) {
|
if (vApp.getStatus().equals(Status.POWERED_ON.getValue())) {
|
||||||
try {
|
try {
|
||||||
Task shutdownTask = vappClient.shutdown(vAppUri);
|
Task shutdownTask = vAppClient.shutdown(vAppURI);
|
||||||
retryTaskSuccess.apply(shutdownTask);
|
retryTaskSuccess.apply(shutdownTask);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// keep going; cleanup as much as possible
|
// keep going; cleanup as much as possible
|
||||||
logger.warn(e, "Continuing cleanup after error shutting down VApp %s", vApp);
|
logger.warn(e, "Continuing cleanup after error shutting down VApp %s", vApp.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,25 +392,27 @@ public abstract class BaseVCloudDirectorClientLiveTest extends BaseVersionedServ
|
||||||
if (vApp.isDeployed()) {
|
if (vApp.isDeployed()) {
|
||||||
try {
|
try {
|
||||||
UndeployVAppParams params = UndeployVAppParams.builder().build();
|
UndeployVAppParams params = UndeployVAppParams.builder().build();
|
||||||
Task undeployTask = vappClient.undeploy(vAppUri, params);
|
Task undeployTask = vAppClient.undeploy(vAppURI, params);
|
||||||
retryTaskSuccess.apply(undeployTask);
|
retryTaskSuccess.apply(undeployTask);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// keep going; cleanup as much as possible
|
// keep going; cleanup as much as possible
|
||||||
logger.warn(e, "Continuing cleanup after error undeploying VApp %s", vApp);
|
logger.warn(e, "Continuing cleanup after error undeploying VApp %s", vApp.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Task task = vappClient.deleteVApp(vAppUri);
|
Task task = vAppClient.deleteVApp(vAppURI);
|
||||||
assertTaskSucceeds(task);
|
assertTaskSucceeds(task);
|
||||||
|
vAppNames.remove(vApp.getName());
|
||||||
|
logger.info("Deleted VApp %s", vApp.getName());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
try {
|
try {
|
||||||
vApp = vappClient.getVApp(vAppUri); // refresh
|
vApp = vAppClient.getVApp(vAppURI); // Refresh
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
// ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn(e, "Deleting vApp failed: vApp="+vApp);
|
logger.warn(e, "Deleting VApp %s failed (%s)", vApp.getName(), vAppURI.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue