Implented vApp tag support for Terremark Enterprise.

Also added configurable exponential delay between automatic retries.
This commit is contained in:
spasam 2011-07-12 11:21:20 -04:00 committed by Adrian Cole
parent 7c1bf8b057
commit 9852aa6fca
14 changed files with 155 additions and 55 deletions

View File

@ -40,6 +40,8 @@ import com.google.inject.ImplementedBy;
public interface VCloudExpressVApp extends ReferenceType { public interface VCloudExpressVApp extends ReferenceType {
ReferenceType getVDC(); ReferenceType getVDC();
Set<ReferenceType> getExtendedInfo();
Status getStatus(); Status getStatus();
Long getSize(); Long getSize();

View File

@ -21,6 +21,7 @@ package org.jclouds.vcloud.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI; import java.net.URI;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.jclouds.cim.ResourceAllocationSettingData; import org.jclouds.cim.ResourceAllocationSettingData;
@ -41,6 +42,7 @@ public class VCloudExpressVAppImpl implements VCloudExpressVApp {
private final String name; private final String name;
private final URI href; private final URI href;
private final ReferenceType vDC; private final ReferenceType vDC;
private final Set<ReferenceType> extendedInfo;
private final Status status; private final Status status;
private final Long size; private final Long size;
private final ListMultimap<String, String> networkToAddresses; private final ListMultimap<String, String> networkToAddresses;
@ -55,6 +57,14 @@ public class VCloudExpressVAppImpl implements VCloudExpressVApp {
public VCloudExpressVAppImpl(String name, URI href, Status status, Long size, ReferenceType vDC, public VCloudExpressVAppImpl(String name, URI href, Status status, Long size, ReferenceType vDC,
ListMultimap<String, String> networkToAddresses, Integer osType, String operatingSystemDescription, ListMultimap<String, String> networkToAddresses, Integer osType, String operatingSystemDescription,
VirtualSystemSettingData system, Set<ResourceAllocationSettingData> resourceAllocations) { VirtualSystemSettingData system, Set<ResourceAllocationSettingData> resourceAllocations) {
this(name, href, status, size, vDC, networkToAddresses, osType, operatingSystemDescription, system,
resourceAllocations, new HashSet<ReferenceType>());
}
public VCloudExpressVAppImpl(String name, URI href, Status status, Long size, ReferenceType vDC,
ListMultimap<String, String> networkToAddresses, Integer osType, String operatingSystemDescription,
VirtualSystemSettingData system, Set<ResourceAllocationSettingData> resourceAllocations,
Set<ReferenceType> extendedInfo) {
this.name = checkNotNull(name, "name"); this.name = checkNotNull(name, "name");
this.href = checkNotNull(href, "href"); this.href = checkNotNull(href, "href");
this.status = checkNotNull(status, "status"); this.status = checkNotNull(status, "status");
@ -65,6 +75,7 @@ public class VCloudExpressVAppImpl implements VCloudExpressVApp {
this.operatingSystemDescription = operatingSystemDescription; this.operatingSystemDescription = operatingSystemDescription;
this.system = system; this.system = system;
this.resourceAllocations = checkNotNull(resourceAllocations, "resourceAllocations"); this.resourceAllocations = checkNotNull(resourceAllocations, "resourceAllocations");
this.extendedInfo = extendedInfo;
} }
@Override @Override
@ -102,6 +113,11 @@ public class VCloudExpressVAppImpl implements VCloudExpressVApp {
return vDC; return vDC;
} }
@Override
public Set<ReferenceType> getExtendedInfo() {
return extendedInfo;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@ -116,6 +132,7 @@ public class VCloudExpressVAppImpl implements VCloudExpressVApp {
result = prime * result + ((status == null) ? 0 : status.hashCode()); result = prime * result + ((status == null) ? 0 : status.hashCode());
result = prime * result + ((system == null) ? 0 : system.hashCode()); result = prime * result + ((system == null) ? 0 : system.hashCode());
result = prime * result + ((vDC == null) ? 0 : vDC.hashCode()); result = prime * result + ((vDC == null) ? 0 : vDC.hashCode());
result = prime * result + ((extendedInfo == null) ? 0 : extendedInfo.hashCode());
return result; return result;
} }
@ -178,6 +195,11 @@ public class VCloudExpressVAppImpl implements VCloudExpressVApp {
return false; return false;
} else if (!vDC.equals(other.vDC)) } else if (!vDC.equals(other.vDC))
return false; return false;
if (extendedInfo == null) {
if (other.extendedInfo != null)
return false;
} else if (!extendedInfo.equals(other.extendedInfo))
return false;
return true; return true;
} }
@ -201,7 +223,7 @@ public class VCloudExpressVAppImpl implements VCloudExpressVApp {
return "[href=" + href + ", name=" + name + ", networkToAddresses=" + networkToAddresses + ", osType=" + osType return "[href=" + href + ", name=" + name + ", networkToAddresses=" + networkToAddresses + ", osType=" + osType
+ ", operatingSystemDescription=" + operatingSystemDescription + ", resourceAllocationByType=" + ", operatingSystemDescription=" + operatingSystemDescription + ", resourceAllocationByType="
+ resourceAllocations + ", size=" + size + ", status=" + status + ", system=" + system + ", vDC=" + vDC + resourceAllocations + ", size=" + size + ", status=" + status + ", system=" + system + ", vDC=" + vDC
+ "]"; + ", extendedInfo=" + extendedInfo + "]";
} }
@Override @Override

View File

@ -79,10 +79,11 @@ public class VCloudExpressVAppHandler extends ParseSax.HandlerWithResult<VCloudE
protected URI location; protected URI location;
protected Long size; protected Long size;
protected ReferenceType vDC; protected ReferenceType vDC;
protected Set<ReferenceType> extendedInfo = Sets.newLinkedHashSet();
public VCloudExpressVApp getResult() { public VCloudExpressVApp getResult() {
return new VCloudExpressVAppImpl(name, location, status, size, vDC, networkToAddresses, osType, return new VCloudExpressVAppImpl(name, location, status, size, vDC, networkToAddresses, osType,
operatingSystemDescription, system, allocations); operatingSystemDescription, system, allocations, extendedInfo);
} }
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
@ -99,8 +100,12 @@ public class VCloudExpressVAppHandler extends ParseSax.HandlerWithResult<VCloudE
if (attributes.containsKey("size")) if (attributes.containsKey("size"))
size = new Long(attributes.get("size")); size = new Long(attributes.get("size"));
} else if (qName.equals("Link")) { // type should never be missing } else if (qName.equals("Link")) { // type should never be missing
if (attributes.containsKey("type") && attributes.get("type").equals(VCloudExpressMediaType.VDC_XML)) { if (attributes.containsKey("type")) {
vDC = newReferenceType(attributes); if (attributes.get("type").equals(VCloudExpressMediaType.VDC_XML)) {
vDC = newReferenceType(attributes);
} else {
extendedInfo.add(newReferenceType(attributes));
}
} }
} else if (qName.equals("OperatingSystemSection")) { } else if (qName.equals("OperatingSystemSection")) {
inOs = true; inOs = true;

View File

@ -129,6 +129,15 @@ public interface Constants {
* the maximum tries of a single command is bounded. * the maximum tries of a single command is bounded.
*/ */
public static final String PROPERTY_MAX_RETRIES = "jclouds.max-retries"; public static final String PROPERTY_MAX_RETRIES = "jclouds.max-retries";
/**
* Long property.
* <p/>
* Commands are retried, if the problem on the server side was a resolvable conflict. However,
* the maximum tries of a single command is bounded. If {@link #PROPERTY_MAX_RETRIES} is greater
* than zero, this property is used to determine the start delay. The delay is based on exponential
* backoff algorithm. Default value for this property is 50 milliseconds.
*/
public static final String PROPERTY_RETRY_DELAY_START = "jclouds.retries-delay-start";
/** /**
* Integer property. * Integer property.
* <p/> * <p/>

View File

@ -38,6 +38,7 @@ import static org.jclouds.Constants.PROPERTY_PROXY_PORT;
import static org.jclouds.Constants.PROPERTY_PROXY_SYSTEM; import static org.jclouds.Constants.PROPERTY_PROXY_SYSTEM;
import static org.jclouds.Constants.PROPERTY_PROXY_USER; import static org.jclouds.Constants.PROPERTY_PROXY_USER;
import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME; import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME;
import static org.jclouds.Constants.PROPERTY_RETRY_DELAY_START;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT; import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT;
import static org.jclouds.Constants.PROPERTY_TRUST_ALL_CERTS; import static org.jclouds.Constants.PROPERTY_TRUST_ALL_CERTS;
@ -137,6 +138,14 @@ public class PropertiesBuilder {
return this; return this;
} }
/**
* @see org.jclouds.Constants.PROPERTY_RETRY_DELAY_START
*/
public PropertiesBuilder withRetriesDelayStart(long delayStart) {
properties.setProperty(PROPERTY_RETRY_DELAY_START, Long.toString(delayStart));
return this;
}
/** /**
* @see org.jclouds.Constants.PROPERTY_MAX_REDIRECTS * @see org.jclouds.Constants.PROPERTY_MAX_REDIRECTS
*/ */

View File

@ -59,6 +59,10 @@ public class FutureIterables {
@Named(Constants.PROPERTY_MAX_RETRIES) @Named(Constants.PROPERTY_MAX_RETRIES)
private static int maxRetries = 5; private static int maxRetries = 5;
@Inject(optional = true)
@Named(Constants.PROPERTY_RETRY_DELAY_START)
private static long delayStart = 50L;
@Inject(optional = true) @Inject(optional = true)
private static BackoffLimitedRetryHandler retryHandler = BackoffLimitedRetryHandler.INSTANCE; private static BackoffLimitedRetryHandler retryHandler = BackoffLimitedRetryHandler.INSTANCE;
@ -91,8 +95,8 @@ public class FutureIterables {
exceptions = awaitCompletion(responses, exec, maxTime, logger, logPrefix); exceptions = awaitCompletion(responses, exec, maxTime, logger, logPrefix);
if (exceptions.size() > 0) { if (exceptions.size() > 0) {
fromIterable = exceptions.keySet(); fromIterable = exceptions.keySet();
retryHandler.imposeBackoffExponentialDelay(i + 1, String.format("error %s: %s: %s", logPrefix, retryHandler.imposeBackoffExponentialDelay(delayStart, 2, i + 1, maxRetries,
fromIterable, exceptions)); String.format("error %s: %s: %s", logPrefix, fromIterable, exceptions));
} else { } else {
break; break;
} }

View File

@ -86,6 +86,10 @@ public class BackoffLimitedRetryHandler implements HttpRetryHandler, IOException
@Named(Constants.PROPERTY_MAX_RETRIES) @Named(Constants.PROPERTY_MAX_RETRIES)
private int retryCountLimit = 5; private int retryCountLimit = 5;
@Inject(optional = true)
@Named(Constants.PROPERTY_RETRY_DELAY_START)
private long delayStart = 50L;
@Resource @Resource
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
@ -115,7 +119,7 @@ public class BackoffLimitedRetryHandler implements HttpRetryHandler, IOException
} }
public void imposeBackoffExponentialDelay(int failureCount, String commandDescription) { public void imposeBackoffExponentialDelay(int failureCount, String commandDescription) {
imposeBackoffExponentialDelay(50L, 2, failureCount, retryCountLimit, commandDescription); imposeBackoffExponentialDelay(delayStart, 2, failureCount, retryCountLimit, commandDescription);
} }
public void imposeBackoffExponentialDelay(long period, int pow, int failureCount, int max, String commandDescription) { public void imposeBackoffExponentialDelay(long period, int pow, int failureCount, int max, String commandDescription) {

View File

@ -36,7 +36,7 @@
<properties> <properties>
<test.trmk-ecloud.endpoint>https://services.enterprisecloud.terremark.com/api</test.trmk-ecloud.endpoint> <test.trmk-ecloud.endpoint>https://services.enterprisecloud.terremark.com/api</test.trmk-ecloud.endpoint>
<test.trmk-ecloud.apiversion>0.8b-ext2.7</test.trmk-ecloud.apiversion> <test.trmk-ecloud.apiversion>0.8b-ext2.8</test.trmk-ecloud.apiversion>
<test.trmk-ecloud.identity>FIXME</test.trmk-ecloud.identity> <test.trmk-ecloud.identity>FIXME</test.trmk-ecloud.identity>
<test.trmk-ecloud.credential>FIXME</test.trmk-ecloud.credential> <test.trmk-ecloud.credential>FIXME</test.trmk-ecloud.credential>
</properties> </properties>

View File

@ -25,6 +25,7 @@ import static org.jclouds.vcloud.terremark.TerremarkECloudMediaType.INTERNETSERV
import static org.jclouds.vcloud.terremark.TerremarkECloudMediaType.IPADDRESS_LIST_XML; import static org.jclouds.vcloud.terremark.TerremarkECloudMediaType.IPADDRESS_LIST_XML;
import static org.jclouds.vcloud.terremark.TerremarkECloudMediaType.KEYSLIST_XML; import static org.jclouds.vcloud.terremark.TerremarkECloudMediaType.KEYSLIST_XML;
import static org.jclouds.vcloud.terremark.TerremarkECloudMediaType.PUBLICIP_XML; import static org.jclouds.vcloud.terremark.TerremarkECloudMediaType.PUBLICIP_XML;
import static org.jclouds.vcloud.terremark.TerremarkECloudMediaType.VAPPEXTINFO_XML;
import java.net.URI; import java.net.URI;
import java.util.Set; import java.util.Set;
@ -55,6 +56,7 @@ import org.jclouds.vcloud.terremark.domain.KeyPair;
import org.jclouds.vcloud.terremark.domain.Protocol; import org.jclouds.vcloud.terremark.domain.Protocol;
import org.jclouds.vcloud.terremark.domain.PublicIpAddress; import org.jclouds.vcloud.terremark.domain.PublicIpAddress;
import org.jclouds.vcloud.terremark.domain.TerremarkNetwork; import org.jclouds.vcloud.terremark.domain.TerremarkNetwork;
import org.jclouds.vcloud.terremark.domain.VAppExtendedInfo;
import org.jclouds.vcloud.terremark.domain.TerremarkOrgNetwork; import org.jclouds.vcloud.terremark.domain.TerremarkOrgNetwork;
import org.jclouds.vcloud.terremark.functions.OrgURIToKeysListEndpoint; import org.jclouds.vcloud.terremark.functions.OrgURIToKeysListEndpoint;
import org.jclouds.vcloud.terremark.functions.VDCURIToInternetServicesEndpoint; import org.jclouds.vcloud.terremark.functions.VDCURIToInternetServicesEndpoint;
@ -69,6 +71,7 @@ import org.jclouds.vcloud.terremark.xml.KeyPairsHandler;
import org.jclouds.vcloud.terremark.xml.PublicIpAddressesHandler; import org.jclouds.vcloud.terremark.xml.PublicIpAddressesHandler;
import org.jclouds.vcloud.terremark.xml.TerremarkNetworkHandler; import org.jclouds.vcloud.terremark.xml.TerremarkNetworkHandler;
import org.jclouds.vcloud.terremark.xml.TerremarkOrgNetworkFromTerremarkVCloudExpressNetworkHandler; import org.jclouds.vcloud.terremark.xml.TerremarkOrgNetworkFromTerremarkVCloudExpressNetworkHandler;
import org.jclouds.vcloud.terremark.xml.VAppExtendedInfoHandler;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
@ -250,4 +253,13 @@ public interface TerremarkECloudAsyncClient extends TerremarkVCloudAsyncClient {
@XMLResponseParser(IpAddressesHandler.class) @XMLResponseParser(IpAddressesHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<IpAddress>> getIpAddresses(@EndpointParam URI network); ListenableFuture<? extends Set<IpAddress>> getIpAddresses(@EndpointParam URI network);
/**
* @see TerremarkVCloudExpressClient#getInternetService
*/
@GET
@Consumes(VAPPEXTINFO_XML)
@XMLResponseParser(VAppExtendedInfoHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VAppExtendedInfo> getVAppExtendedInfo(@EndpointParam URI href);
} }

View File

@ -29,6 +29,7 @@ import org.jclouds.vcloud.terremark.domain.IpAddress;
import org.jclouds.vcloud.terremark.domain.PublicIpAddress; import org.jclouds.vcloud.terremark.domain.PublicIpAddress;
import org.jclouds.vcloud.terremark.domain.TerremarkNetwork; import org.jclouds.vcloud.terremark.domain.TerremarkNetwork;
import org.jclouds.vcloud.terremark.domain.TerremarkOrgNetwork; import org.jclouds.vcloud.terremark.domain.TerremarkOrgNetwork;
import org.jclouds.vcloud.terremark.domain.VAppExtendedInfo;
/** /**
* Provides access to VCloud resources via their REST API. * Provides access to VCloud resources via their REST API.
@ -58,4 +59,11 @@ public interface TerremarkECloudClient extends TerremarkVCloudClient {
Set<IpAddress> getIpAddresses(URI network); Set<IpAddress> getIpAddresses(URI network);
/**
* Returns extended information for the vApp.
*
* @param vApp The URI at which the vApp information is available.
* @return Extended vApp information like tags, long name, network adapter information.
*/
VAppExtendedInfo getVAppExtendedInfo(URI href);
} }

View File

@ -22,7 +22,7 @@ import javax.ws.rs.core.MediaType;
/** /**
* Resource Types used in Terremark eCloud * Resource Types used in Terremark eCloud
* *
* @see MediaType * @see MediaType
*/ */
public interface TerremarkECloudMediaType extends TerremarkVCloudMediaType { public interface TerremarkECloudMediaType extends TerremarkVCloudMediaType {
@ -35,7 +35,7 @@ public interface TerremarkECloudMediaType extends TerremarkVCloudMediaType {
* "application/vnd.tmrk.ecloud.publicIp+xml" * "application/vnd.tmrk.ecloud.publicIp+xml"
*/ */
public final static MediaType PUBLICIP_XML_TYPE = new MediaType("application", "vnd.tmrk.ecloud.publicIp+xml"); public final static MediaType PUBLICIP_XML_TYPE = new MediaType("application", "vnd.tmrk.ecloud.publicIp+xml");
/** /**
* "application/vnd.tmrk.ecloud.internetService+xml" * "application/vnd.tmrk.ecloud.internetService+xml"
*/ */
@ -66,15 +66,24 @@ public interface TerremarkECloudMediaType extends TerremarkVCloudMediaType {
* "application/vnd.tmrk.ecloud.keysList+xml" * "application/vnd.tmrk.ecloud.keysList+xml"
*/ */
public final static MediaType KEYSLIST_XML_TYPE = new MediaType("application", "vnd.tmrk.ecloud.keysList+xml"); public final static MediaType KEYSLIST_XML_TYPE = new MediaType("application", "vnd.tmrk.ecloud.keysList+xml");
/** /**
* "application/vnd.tmrk.ecloud.ipAddressList+xml" * "application/vnd.tmrk.ecloud.ipAddressList+xml"
*/ */
public final static String IPADDRESS_LIST_XML = "application/vnd.tmrk.ecloud.ipAddressList+xml"; public final static String IPADDRESS_LIST_XML = "application/vnd.tmrk.ecloud.ipAddressList+xml";
/** /**
* "application/vnd.tmrk.ecloud.ipAddressList+xml" * "application/vnd.tmrk.ecloud.ipAddressList+xml"
*/ */
public final static MediaType IPADDRESSES_LIST_XML_TYPE = new MediaType("application", "vnd.tmrk.ecloud.ipAddressList+xml"); public final static MediaType IPADDRESSES_LIST_XML_TYPE = new MediaType("application", "vnd.tmrk.ecloud.ipAddressList+xml");
/**
* "application/vnd.tmrk.ecloud.vApp+xml"
*/
public final static String VAPPEXTINFO_XML = "application/vnd.tmrk.ecloud.vApp+xml";
/**
* "application/vnd.tmrk.ecloud.vApp+xml"
*/
public final static MediaType VAPPEXTINFO_XML_TYPE = new MediaType("application", "vnd.tmrk.ecloud.vApp+xml");
} }

View File

@ -38,10 +38,10 @@ public class TerremarkECloudPropertiesBuilder extends TerremarkVCloudPropertiesB
protected Properties defaultProperties() { protected Properties defaultProperties() {
Properties properties = super.defaultProperties(); Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_ISO3166_CODES, "US-FL,NL-NH"); properties.setProperty(PROPERTY_ISO3166_CODES, "US-FL,NL-NH");
properties.setProperty(PROPERTY_API_VERSION, "0.8b-ext2.7"); properties.setProperty(PROPERTY_API_VERSION, "0.8b-ext2.8");
properties.setProperty(PROPERTY_ENDPOINT, "https://services.enterprisecloud.terremark.com/api"); properties.setProperty(PROPERTY_ENDPOINT, "https://services.enterprisecloud.terremark.com/api");
properties.setProperty(PROPERTY_TERREMARK_EXTENSION_NAME, "eCloudExtensions"); properties.setProperty(PROPERTY_TERREMARK_EXTENSION_NAME, "eCloudExtensions");
properties.setProperty(PROPERTY_TERREMARK_EXTENSION_VERSION, "2.7"); properties.setProperty(PROPERTY_TERREMARK_EXTENSION_VERSION, "2.8");
// default for ubuntu // default for ubuntu
properties.setProperty(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED, 360l * 1000l + ""); properties.setProperty(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED, 360l * 1000l + "");
// ubuntu image has a problem with sftp // ubuntu image has a problem with sftp

View File

@ -82,6 +82,7 @@ import org.jclouds.vcloud.terremark.xml.NodesHandler;
import org.jclouds.vcloud.terremark.xml.PublicIpAddressesHandler; import org.jclouds.vcloud.terremark.xml.PublicIpAddressesHandler;
import org.jclouds.vcloud.terremark.xml.TerremarkOrgNetworkFromTerremarkVCloudExpressNetworkHandler; import org.jclouds.vcloud.terremark.xml.TerremarkOrgNetworkFromTerremarkVCloudExpressNetworkHandler;
import org.jclouds.vcloud.terremark.xml.TerremarkVDCHandler; import org.jclouds.vcloud.terremark.xml.TerremarkVDCHandler;
import org.jclouds.vcloud.terremark.xml.VAppExtendedInfoHandler;
import org.jclouds.vcloud.xml.VCloudExpressCatalogHandler; import org.jclouds.vcloud.xml.VCloudExpressCatalogHandler;
import org.jclouds.vcloud.xml.VCloudExpressVAppHandler; import org.jclouds.vcloud.xml.VCloudExpressVAppHandler;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -308,7 +309,7 @@ public class TerremarkECloudAsyncClientTest extends RestClientTest<TerremarkEClo
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.ecloud.internetService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.ecloud.internetService+xml\n");
assertPayloadEquals(request, assertPayloadEquals(request,
Strings2.toStringAndClose(getClass().getResourceAsStream("/terremark/CreateInternetService-test2.xml")) Strings2.toStringAndClose(getClass().getResourceAsStream("/terremark/CreateInternetService-test2.xml"))
.replace("vCloudExpressExtensions-1.6", "eCloudExtensions-2.7"), .replace("vCloudExpressExtensions-1.6", "eCloudExtensions-2.8"),
"application/vnd.tmrk.ecloud.internetService+xml", false); "application/vnd.tmrk.ecloud.internetService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
@ -328,7 +329,7 @@ public class TerremarkECloudAsyncClientTest extends RestClientTest<TerremarkEClo
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.ecloud.internetService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.ecloud.internetService+xml\n");
assertPayloadEquals(request, assertPayloadEquals(request,
Strings2.toStringAndClose(getClass().getResourceAsStream("/CreateInternetService-options-test.xml")) Strings2.toStringAndClose(getClass().getResourceAsStream("/CreateInternetService-options-test.xml"))
.replace("vCloudExpressExtensions-1.6", "eCloudExtensions-2.7"), .replace("vCloudExpressExtensions-1.6", "eCloudExtensions-2.8"),
"application/vnd.tmrk.ecloud.internetService+xml", false); "application/vnd.tmrk.ecloud.internetService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InternetServiceHandler.class); assertSaxResponseParserClassEquals(method, InternetServiceHandler.class);
@ -347,7 +348,7 @@ public class TerremarkECloudAsyncClientTest extends RestClientTest<TerremarkEClo
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertPayloadEquals(request, assertPayloadEquals(request,
Strings2.toStringAndClose(getClass().getResourceAsStream("/terremark/CreateNodeService-test2.xml")) Strings2.toStringAndClose(getClass().getResourceAsStream("/terremark/CreateNodeService-test2.xml"))
.replace("vCloudExpressExtensions-1.6", "eCloudExtensions-2.7"), .replace("vCloudExpressExtensions-1.6", "eCloudExtensions-2.8"),
"application/vnd.tmrk.vCloud.nodeService+xml", false); "application/vnd.tmrk.vCloud.nodeService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
@ -368,7 +369,7 @@ public class TerremarkECloudAsyncClientTest extends RestClientTest<TerremarkEClo
assertPayloadEquals(request, assertPayloadEquals(request,
Strings2.toStringAndClose(getClass().getResourceAsStream("/terremark/CreateNodeService-options-test.xml")) Strings2.toStringAndClose(getClass().getResourceAsStream("/terremark/CreateNodeService-options-test.xml"))
.replace("vCloudExpressExtensions-1.6", "eCloudExtensions-2.7"), .replace("vCloudExpressExtensions-1.6", "eCloudExtensions-2.8"),
"application/vnd.tmrk.vCloud.nodeService+xml", false); "application/vnd.tmrk.vCloud.nodeService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class); assertSaxResponseParserClassEquals(method, NodeHandler.class);
@ -403,7 +404,7 @@ public class TerremarkECloudAsyncClientTest extends RestClientTest<TerremarkEClo
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertPayloadEquals( assertPayloadEquals(
request, request,
"<NodeService xmlns=\"urn:tmrk:eCloudExtensions-2.7\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Name>name</Name><Enabled>true</Enabled><Description>eggs</Description></NodeService>", "<NodeService xmlns=\"urn:tmrk:eCloudExtensions-2.8\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Name>name</Name><Enabled>true</Enabled><Description>eggs</Description></NodeService>",
"application/vnd.tmrk.vCloud.nodeService+xml", false); "application/vnd.tmrk.vCloud.nodeService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class); assertSaxResponseParserClassEquals(method, NodeHandler.class);
@ -422,7 +423,7 @@ public class TerremarkECloudAsyncClientTest extends RestClientTest<TerremarkEClo
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertPayloadEquals( assertPayloadEquals(
request, request,
"<NodeService xmlns=\"urn:tmrk:eCloudExtensions-2.7\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Name>name</Name><Enabled>true</Enabled></NodeService>", "<NodeService xmlns=\"urn:tmrk:eCloudExtensions-2.8\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Name>name</Name><Enabled>true</Enabled></NodeService>",
"application/vnd.tmrk.vCloud.nodeService+xml", false); "application/vnd.tmrk.vCloud.nodeService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class); assertSaxResponseParserClassEquals(method, NodeHandler.class);
@ -544,6 +545,21 @@ public class TerremarkECloudAsyncClientTest extends RestClientTest<TerremarkEClo
checkFilters(request); checkFilters(request);
} }
public void testGetExtendedInfo() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkECloudAsyncClient.class.getMethod("getVAppExtendedInfo", URI.class);
HttpRequest request = processor.createRequest(method, URI.create("https://vcloud/extensions/vapp/12"));
assertRequestLineEquals(request, "GET https://vcloud/extensions/vapp/12 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.ecloud.vApp+xml\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VAppExtendedInfoHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
}
@Override @Override
protected void checkFilters(HttpRequest request) { protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1); assertEquals(request.getFilters().size(), 1);

View File

@ -1,104 +1,104 @@
<Catalog <Catalog
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/vdc/691/catalog" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/vdc/691/catalog"
type="application/vnd.vmware.vcloud.catalog+xml" name="Opscode, Inc. Catalog" type="application/vnd.vmware.vcloud.catalog+xml" name="Opscode, Inc. Catalog"
xmlns="http://www.vmware.com/vcloud/v0.8" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.vmware.com/vcloud/v0.8" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CatalogItems> <CatalogItems>
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/36-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/36-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="CentOS 5 (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="CentOS 5 (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/35-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/35-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="CentOS 5 (x86)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="CentOS 5 (x86)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/346-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/346-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="CentOS 5.5 x32" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="CentOS 5.5 x32" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/347-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/347-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="CentOS 5.5 x64" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="CentOS 5.5 x64" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/233-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/233-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="Red Hat Enterprise Linux 5 (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="Red Hat Enterprise Linux 5 (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/107-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/107-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="Red Hat Enterprise Linux 5 (x86)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="Red Hat Enterprise Linux 5 (x86)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/348-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/348-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="Red Hat Enterprise Linux 5.5 x32" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="Red Hat Enterprise Linux 5.5 x32" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/349-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/349-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="Red Hat Enterprise Linux 5.5 x64" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="Red Hat Enterprise Linux 5.5 x64" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/6-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/6-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="Sun Solaris 10 (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="Sun Solaris 10 (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/103-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/103-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="Ubuntu 8.04 LTS (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="Ubuntu 8.04 LTS (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/55-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/55-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="Ubuntu 8.04 LTS (x86)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="Ubuntu 8.04 LTS (x86)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/350-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/350-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="Ubuntu Server 10.04 x32" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="Ubuntu Server 10.04 x32" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/351-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/351-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="Ubuntu Server 10.04 x64" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="Ubuntu Server 10.04 x64" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/325-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/325-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2003 Std. R2 SQL 2005 Std. (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2003 Std. R2 SQL 2005 Std. (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/335-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/335-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2003 Std. R2 SQL 2008 Std. (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2003 Std. R2 SQL 2008 Std. (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/340-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/340-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2008 R2 Std wSQL 2008 R2 Std (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2008 R2 Std wSQL 2008 R2 Std (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/341-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/341-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2008 R2 Std wSQL 2008 R2 Web (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2008 R2 Std wSQL 2008 R2 Web (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/336-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/336-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2008 Std wSQL 2008 Std (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2008 Std wSQL 2008 Std (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/327-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/327-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2008 Std wSQL 2008 Web (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows 2008 Std wSQL 2008 Web (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/249-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/249-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2003 R2 Enterprise Edition (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2003 R2 Enterprise Edition (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/248-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/248-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2003 R2 Enterprise Edition (x86)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2003 R2 Enterprise Edition (x86)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/281-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/281-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2003 R2 Standard Edition (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2003 R2 Standard Edition (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/280-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/280-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2003 R2 Standard Edition (x86)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2003 R2 Standard Edition (x86)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/261-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/261-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Enterprise Edition (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Enterprise Edition (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/307-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/307-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Enterprise Edition (x86)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Enterprise Edition (x86)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/256-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/256-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 R2 Enterprise Edition (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 R2 Enterprise Edition (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/322-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/322-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 R2 Standard Edition (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 R2 Standard Edition (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/270-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/270-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 R2 Web Edition (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 R2 Web Edition (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/269-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/269-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Standard Edition (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Standard Edition (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/267-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/267-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Standard Edition (x86)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Standard Edition (x86)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/277-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/277-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Web Edition (x64)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Web Edition (x64)" />
<CatalogItem <CatalogItem
href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.7/catalogItem/276-691" href="https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.8/catalogItem/276-691"
type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Web Edition (x86)" /> type="application/vnd.vmware.vcloud.catalogItem+xml" name="-Windows Server 2008 Web Edition (x86)" />
</CatalogItems> </CatalogItems>
</Catalog> </Catalog>