Merge branch 'master' of git://github.com/jclouds/jclouds into large-blob

This commit is contained in:
Tibor Kiss 2011-03-06 20:49:24 +01:00
commit f354712f89
83 changed files with 3737 additions and 675 deletions

View File

@ -32,7 +32,7 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.ec2.compute.EC2ComputeService;
import org.jclouds.ec2.compute.domain.RegionAndName;
import org.jclouds.ec2.compute.suppliers.RegionAndNameToImageSupplier;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import com.google.common.base.Supplier;
import com.google.inject.Provides;
@ -59,7 +59,7 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
@Singleton
protected Supplier<Map<RegionAndName, ? extends Image>> provideRegionAndNameToImageSupplierCache(
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final RegionAndNameToImageSupplier supplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<RegionAndName, ? extends Image>>(
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<RegionAndName, ? extends Image>>(
authException, seconds, new Supplier<Map<RegionAndName, ? extends Image>>() {
@Override
public Map<RegionAndName, ? extends Image> get() {

View File

@ -52,9 +52,9 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
@Inject
protected EC2TemplateBuilderImpl(@Memoized Supplier<Set<? extends Location>> locations,
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
Supplier<Location> defaultLocation, Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider, Map<RegionAndName, Image> imageMap) {
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
Supplier<Location> defaultLocation, @Named("DEFAULT") Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider, Map<RegionAndName, Image> imageMap) {
super(locations, images, sizes, defaultLocation, optionsProvider, defaultTemplateProvider);
this.imageMap = imageMap;
}
@ -85,8 +85,7 @@ public class EC2TemplateBuilderImpl extends TemplateBuilderImpl {
if (imageId != null) {
String[] regionName = imageId.split("/");
checkArgument(regionName.length == 2,
"amazon image ids must include the region ( ex. us-east-1/ami-7ea24a17 ) you specified: "
+ imageId);
"amazon image ids must include the region ( ex. us-east-1/ami-7ea24a17 ) you specified: " + imageId);
RegionAndName key = new RegionAndName(regionName[0], regionName[1]);
try {
return imageMap.get(key);

View File

@ -21,6 +21,7 @@ package org.jclouds.vcloud;
import static org.jclouds.vcloud.VCloudMediaType.DEPLOYVAPPPARAMS_XML;
import static org.jclouds.vcloud.VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML;
import static org.jclouds.vcloud.VCloudMediaType.NETWORKCONNECTIONSECTION_XML;
import static org.jclouds.vcloud.VCloudMediaType.TASK_XML;
import static org.jclouds.vcloud.VCloudMediaType.UNDEPLOYVAPPPARAMS_XML;
import static org.jclouds.vcloud.VCloudMediaType.VAPPTEMPLATE_XML;
@ -47,9 +48,9 @@ import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.ParamValidators;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.PayloadParams;
import org.jclouds.rest.annotations.ParamValidators;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
@ -59,8 +60,10 @@ import org.jclouds.vcloud.binders.BindCloneVAppParamsToXmlPayload;
import org.jclouds.vcloud.binders.BindDeployVAppParamsToXmlPayload;
import org.jclouds.vcloud.binders.BindGuestCustomizationSectionToXmlPayload;
import org.jclouds.vcloud.binders.BindInstantiateVAppTemplateParamsToXmlPayload;
import org.jclouds.vcloud.binders.BindNetworkConnectionSectionToXmlPayload;
import org.jclouds.vcloud.binders.BindUndeployVAppParamsToXmlPayload;
import org.jclouds.vcloud.domain.GuestCustomizationSection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
@ -140,9 +143,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(VAppTemplateHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VAppTemplate> findVAppTemplateInOrgCatalogNamed(
@Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String itemName);
@Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String itemName);
/**
* @see VCloudClient#instantiateVAppTemplateInVDC
@ -154,9 +157,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(VAppHandler.class)
@MapBinder(BindInstantiateVAppTemplateParamsToXmlPayload.class)
ListenableFuture<? extends VApp> instantiateVAppTemplateInVDC(@EndpointParam URI vdc,
@PayloadParam("template") URI template,
@PayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName,
InstantiateVAppTemplateOptions... options);
@PayloadParam("template") URI template,
@PayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName,
InstantiateVAppTemplateOptions... options);
/**
* @see VCloudClient#cloneVAppInVDC
@ -168,8 +171,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(TaskHandler.class)
@MapBinder(BindCloneVAppParamsToXmlPayload.class)
ListenableFuture<? extends Task> cloneVAppInVDC(@EndpointParam URI vdc, @PayloadParam("vApp") URI toClone,
@PayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName,
CloneVAppOptions... options);
@PayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, CloneVAppOptions... options);
/**
* @see VCloudClient#captureVAppInVDC
@ -181,9 +183,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(VAppTemplateHandler.class)
@MapBinder(BindCaptureVAppParamsToXmlPayload.class)
ListenableFuture<? extends VAppTemplate> captureVAppInVDC(@EndpointParam URI vdc,
@PayloadParam("vApp") URI toCapture,
@PayloadParam("templateName") @ParamValidators(DnsNameValidator.class) String templateName,
CaptureVAppOptions... options);
@PayloadParam("vApp") URI toCapture,
@PayloadParam("templateName") @ParamValidators(DnsNameValidator.class) String templateName,
CaptureVAppOptions... options);
/**
* @see VCloudClient#findVAppInOrgVDCNamed
@ -193,9 +195,9 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@XMLResponseParser(VAppHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VApp> findVAppInOrgVDCNamed(
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String vAppName);
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String vAppName);
/**
* @see VCloudClient#getVApp
@ -224,8 +226,19 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@Path("/guestCustomizationSection")
@XMLResponseParser(TaskHandler.class)
ListenableFuture<? extends Task> updateGuestCustomizationOfVm(
@EndpointParam URI vm,
@BinderParam(BindGuestCustomizationSectionToXmlPayload.class) GuestCustomizationSection guestCustomizationSection);
@EndpointParam URI vm,
@BinderParam(BindGuestCustomizationSectionToXmlPayload.class) GuestCustomizationSection guestCustomizationSection);
/**
* @see VCloudClient#updateNetworkConnectionOfVm
*/
@PUT
@Consumes(TASK_XML)
@Produces(NETWORKCONNECTIONSECTION_XML)
@Path("/networkConnectionSection")
@XMLResponseParser(TaskHandler.class)
ListenableFuture<? extends Task> updateNetworkConnectionOfVm(@EndpointParam URI vm,
@BinderParam(BindNetworkConnectionSectionToXmlPayload.class) NetworkConnectionSection networkConnectionSection);
/**
* @see VCloudClient#deployVAppOrVm

View File

@ -29,6 +29,7 @@ import javax.annotation.Nullable;
import org.jclouds.concurrent.Timeout;
import org.jclouds.vcloud.domain.GuestCustomizationSection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
@ -48,14 +49,15 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
*/
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface VCloudClient extends CommonVCloudClient {
/**
* Get a Screen Thumbnail for a Virtual Machine
*
* @param vm to snapshot
* @param vm
* to snapshot
*/
InputStream getThumbnailOfVm(URI vm);
/**
* The response to a login request includes a list of the organizations to which the
* authenticated user has access.
@ -68,11 +70,9 @@ public interface VCloudClient extends CommonVCloudClient {
Task cloneVAppInVDC(URI vDC, URI toClone, String newName, CloneVAppOptions... options);
/**
* The captureVApp request creates a vApp template from an instantiated vApp.
* <h4>Note</h4>
* Before it can be captured, a vApp must be undeployed
* The captureVApp request creates a vApp template from an instantiated vApp. <h4>Note</h4>
* Before it can be captured, a vApp must be undeployed
*
* @param vDC
* @param toClone
@ -97,6 +97,17 @@ public interface VCloudClient extends CommonVCloudClient {
*/
Task updateGuestCustomizationOfVm(URI vm, GuestCustomizationSection guestCustomizationSection);
/**
* Modify the Network Connection Section of a Virtual Machine
*
* @param vm
* uri to modify
* @param updated
* networkConnectionSection
* @return task in progress
*/
Task updateNetworkConnectionOfVm(URI vm, NetworkConnectionSection guestCustomizationSection);
/**
* returns the vapp template corresponding to a catalog item in the catalog associated with the
* specified name. Note that the org and catalog parameters can be null to choose default.
@ -112,7 +123,7 @@ public interface VCloudClient extends CommonVCloudClient {
* if you specified an org, catalog, or catalog item name that isn't present
*/
VAppTemplate findVAppTemplateInOrgCatalogNamed(@Nullable String orgName, @Nullable String catalogName,
String itemName);
String itemName);
VApp findVAppInOrgVDCNamed(@Nullable String orgName, @Nullable String catalogName, String vAppName);

View File

@ -0,0 +1,109 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE;
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_SCHEMA;
import java.util.Properties;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.logging.Logger;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.vcloud.domain.NetworkConnection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import com.google.common.base.Throwables;
import com.google.inject.Inject;
import com.jamesmurty.utils.XMLBuilder;
/**
*
* @author Adrian Cole
*
*/
@Singleton
public class BindNetworkConnectionSectionToXmlPayload extends BindToStringPayload {
@Resource
protected Logger logger = Logger.NULL;
protected final String ns;
protected final String schema;
@Inject
public BindNetworkConnectionSectionToXmlPayload(BindToStringPayload stringBinder,
@Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns, @Named(PROPERTY_VCLOUD_XML_SCHEMA) String schema) {
this.ns = ns;
this.schema = schema;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object payload) {
checkArgument(checkNotNull(payload, "NetworkConnectionSection") instanceof NetworkConnectionSection,
"this binder is only valid for NetworkConnectionSection!");
NetworkConnectionSection net = NetworkConnectionSection.class.cast(payload);
XMLBuilder networkConnectionSection;
try {
networkConnectionSection = XMLBuilder.create("NetworkConnectionSection").a("xmlns", ns)
.a("xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1").a("type", net.getType())
.a("href", net.getHref().toASCIIString()).a("ovf:required", "false");
networkConnectionSection.e("ovf:Info").t(net.getInfo());
if (net.getPrimaryNetworkConnectionIndex() != null)
networkConnectionSection.e("PrimaryNetworkConnectionIndex").t(
net.getPrimaryNetworkConnectionIndex().toString());
for (NetworkConnection networkConnection : net.getConnections()) {
XMLBuilder networkConnectionSectionChild = networkConnectionSection.e("NetworkConnection").a("network",
networkConnection.getNetwork());
networkConnectionSectionChild.e("NetworkConnectionIndex").t(
networkConnection.getNetworkConnectionIndex() + "");
if (networkConnection.getExternalIpAddress() != null)
networkConnectionSectionChild.e("ExternalIpAddress").t(networkConnection.getExternalIpAddress());
if (networkConnection.getIpAddress() != null)
networkConnectionSectionChild.e("IpAddress").t(networkConnection.getIpAddress());
networkConnectionSectionChild.e("IsConnected").t(networkConnection.isConnected() + "");
if (networkConnection.getMACAddress() != null)
networkConnectionSectionChild.e("MACAddress").t(networkConnection.getMACAddress());
if (networkConnection.getIpAddressAllocationMode() != null)
networkConnectionSectionChild.e("IpAddressAllocationMode").t(
networkConnection.getIpAddressAllocationMode().toString());
}
if (net.getEdit() != null)
networkConnectionSection.e("Link").a("rel", "edit").a("type", net.getType())
.a("href", net.getHref().toASCIIString());
Properties outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
request = super.bindToRequest(request, networkConnectionSection.asString(outputProperties));
request.getPayload().getContentMetadata().setContentType(net.getType());
} catch (Exception e) {
Throwables.propagate(e);
}
return request;
}
}

View File

@ -20,13 +20,15 @@
package org.jclouds.vcloud.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterables.filter;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getCredentialsFrom;
import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getPrivateIpsFromVApp;
import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getPublicIpsFromVApp;
import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getIpsFromVApp;
import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.toComputeOs;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
@ -38,6 +40,7 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger;
import org.jclouds.util.InetAddresses2.IsPrivateIPAddress;
import org.jclouds.vcloud.domain.Status;
import org.jclouds.vcloud.domain.VApp;
@ -58,7 +61,7 @@ public class VAppToNodeMetadata implements Function<VApp, NodeMetadata> {
@Inject
protected VAppToNodeMetadata(Map<Status, NodeState> vAppStatusToNodeState, Map<String, Credentials> credentialStore,
FindLocationForResource findLocationForResourceInVDC, Function<VApp, Hardware> hardwareForVApp) {
FindLocationForResource findLocationForResourceInVDC, Function<VApp, Hardware> hardwareForVApp) {
this.hardwareForVApp = checkNotNull(hardwareForVApp, "hardwareForVApp");
this.findLocationForResourceInVDC = checkNotNull(findLocationForResourceInVDC, "findLocationForResourceInVDC");
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
@ -75,8 +78,9 @@ public class VAppToNodeMetadata implements Function<VApp, NodeMetadata> {
builder.operatingSystem(toComputeOs(from, null));
builder.hardware(hardwareForVApp.apply(from));
builder.state(vAppStatusToNodeState.get(from.getStatus()));
builder.publicAddresses(getPublicIpsFromVApp(from));
builder.privateAddresses(getPrivateIpsFromVApp(from));
Set<String> addresses = getIpsFromVApp(from);
builder.publicAddresses(filter(addresses, not(IsPrivateIPAddress.INSTANCE)));
builder.privateAddresses(filter(addresses, IsPrivateIPAddress.INSTANCE));
builder.credentials(getCredentialsFrom(from));
Credentials fromApi = getCredentialsFrom(from);
if (fromApi != null && !credentialStore.containsKey("node#" + from.getHref().toASCIIString()))

View File

@ -44,9 +44,9 @@ public class VCloudTemplateBuilderImpl extends TemplateBuilderImpl {
@Inject
protected VCloudTemplateBuilderImpl(@Memoized Supplier<Set<? extends Location>> locations,
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
Supplier<Location> defaultLocation, Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider) {
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
Supplier<Location> defaultLocation, @Named("DEFAULT") Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider) {
super(locations, images, sizes, defaultLocation, optionsProvider, defaultTemplateProvider);
}
@ -58,6 +58,8 @@ public class VCloudTemplateBuilderImpl extends TemplateBuilderImpl {
VCloudTemplateOptions eTo = VCloudTemplateOptions.class.cast(to);
if (eFrom.getCustomizationScript() != null)
eTo.customizationScript(eFrom.getCustomizationScript());
if (eFrom.getIpAddressAllocationMode() != null)
eTo.ipAddressAllocationMode(eFrom.getIpAddressAllocationMode());
}
}

View File

@ -24,6 +24,7 @@ import java.util.Arrays;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.io.Payload;
import org.jclouds.util.Preconditions2;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
/**
* Contains options supported in the {@code ComputeService#runNode} operation on the "vcloud"
@ -45,6 +46,7 @@ import org.jclouds.util.Preconditions2;
public class VCloudTemplateOptions extends TemplateOptions {
private String customizationScript = null;
private IpAddressAllocationMode ipAddressAllocationMode = null;
public static final VCloudTemplateOptions NONE = new VCloudTemplateOptions();
@ -57,8 +59,15 @@ public class VCloudTemplateOptions extends TemplateOptions {
return this;
}
public static class Builder {
/**
* Specifies the ipAddressAllocationMode used to for network interfaces on the VMs
*/
public VCloudTemplateOptions ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
this.ipAddressAllocationMode = ipAddressAllocationMode;
return this;
}
public static class Builder {
/**
* @see VCloudTemplateOptions#customizationScript
*/
@ -67,6 +76,14 @@ public class VCloudTemplateOptions extends TemplateOptions {
return VCloudTemplateOptions.class.cast(options.customizationScript(customizationScript));
}
/**
* @see VCloudTemplateOptions#ipAddressAllocationMode
*/
public static VCloudTemplateOptions ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
VCloudTemplateOptions options = new VCloudTemplateOptions();
return VCloudTemplateOptions.class.cast(options.ipAddressAllocationMode(ipAddressAllocationMode));
}
// methods that only facilitate returning the correct object type
/**
* @see TemplateOptions#inboundPorts
@ -125,6 +142,13 @@ public class VCloudTemplateOptions extends TemplateOptions {
return customizationScript;
}
/**
* @return ipAddressAllocationMode on the vms
*/
public IpAddressAllocationMode getIpAddressAllocationMode() {
return ipAddressAllocationMode;
}
// methods that only facilitate returning the correct object type
/**
@ -212,6 +236,7 @@ public class VCloudTemplateOptions extends TemplateOptions {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((customizationScript == null) ? 0 : customizationScript.hashCode());
result = prime * result + ((ipAddressAllocationMode == null) ? 0 : ipAddressAllocationMode.hashCode());
return result;
}
@ -229,15 +254,17 @@ public class VCloudTemplateOptions extends TemplateOptions {
return false;
} else if (!customizationScript.equals(other.customizationScript))
return false;
if (ipAddressAllocationMode != other.ipAddressAllocationMode)
return false;
return true;
}
@Override
public String toString() {
return "[customizationScript=" + customizationScript + ", inboundPorts=" + Arrays.toString(inboundPorts)
+ ", privateKey=" + (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript="
+ (script != null) + ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata
+ "]";
return "[customizationScript=" + (customizationScript != null) + ", ipAddressAllocationMode="
+ ipAddressAllocationMode + ", inboundPorts=" + Arrays.toString(inboundPorts) + ", privateKey="
+ (privateKey != null) + ", publicKey=" + (publicKey != null) + ", runScript=" + (script != null)
+ ", port:seconds=" + port + ":" + seconds + ", metadata/details: " + includeMetadata + "]";
}
}

View File

@ -38,11 +38,16 @@ import org.jclouds.logging.Logger;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
import org.jclouds.vcloud.domain.GuestCustomizationSection;
import org.jclouds.vcloud.domain.NetworkConnection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import org.jclouds.vcloud.domain.NetworkConnectionSection.Builder;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.Vm;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
@ -50,7 +55,8 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole
*/
@Singleton
public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn implements CreateNodeWithGroupEncodedIntoName {
public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn implements
CreateNodeWithGroupEncodedIntoName {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
@ -60,8 +66,8 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
protected final Predicate<URI> successTester;
@Inject
protected InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn(Predicate<URI> successTester, VCloudClient client,
GetNodeMetadataStrategy getNode) {
protected InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn(Predicate<URI> successTester,
VCloudClient client, GetNodeMetadataStrategy getNode) {
this.client = client;
this.successTester = successTester;
this.getNode = getNode;
@ -70,13 +76,15 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
@Override
public NodeMetadata createNodeWithGroupEncodedIntoName(String tag, String name, Template template) {
InstantiateVAppTemplateOptions options = processorCount((int) getCores(template.getHardware())).memory(
template.getHardware().getRam()).disk(
(long) ((template.getHardware().getVolumes().get(0).getSize()) * 1024 * 1024l));
template.getHardware().getRam()).disk(
(long) ((template.getHardware().getVolumes().get(0).getSize()) * 1024 * 1024l));
String customizationScript = null;
IpAddressAllocationMode ipAddressAllocationMode = null;
if (template.getOptions() instanceof VCloudTemplateOptions) {
customizationScript = VCloudTemplateOptions.class.cast(template.getOptions()).getCustomizationScript();
if (customizationScript != null) {
ipAddressAllocationMode = VCloudTemplateOptions.class.cast(template.getOptions()).getIpAddressAllocationMode();
if (customizationScript != null || ipAddressAllocationMode != null) {
options.customizeOnInstantiate(false);
options.deploy(false);
options.powerOn(false);
@ -96,39 +104,64 @@ public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployA
Task task = vAppResponse.getTasks().get(0);
if (customizationScript == null) {
if (customizationScript == null && ipAddressAllocationMode == null) {
return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task);
} else {
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String
.format("failed to %s %s: %s", "instantiate", vAppResponse.getName(), task));
throw new RuntimeException(
String.format("failed to %s %s: %s", "instantiate", vAppResponse.getName(), task));
}
Vm vm = Iterables.get(client.getVApp(vAppResponse.getHref()).getChildren(), 0);
GuestCustomizationSection guestConfiguration = vm.getGuestCustomizationSection();
// guestConfiguration
// .setCustomizationScript(guestConfiguration.getCustomizationScript()
// != null ?
// guestConfiguration
// .getCustomizationScript()
// + "\n" + customizationScript : customizationScript);
guestConfiguration.setCustomizationScript(customizationScript);
task = client.updateGuestCustomizationOfVm(vm.getHref(), guestConfiguration);
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "updateGuestCustomizationOfVm", vm
.getName(), task));
}
if (customizationScript != null)
updateVmWithCustomizationScript(vm, customizationScript);
if (ipAddressAllocationMode != null)
updateVmWithIpAddressAllocationMode(vm, ipAddressAllocationMode);
task = client.deployAndPowerOnVAppOrVm(vAppResponse.getHref());
return blockOnDeployAndPowerOnIfConfigured(options, vAppResponse, task);
}
}
public void updateVmWithCustomizationScript(Vm vm, String customizationScript) {
Task task;
GuestCustomizationSection guestConfiguration = vm.getGuestCustomizationSection();
// TODO: determine if the server version is beyond 1.0.0, and if so append to, but
// not overwrite the customization script. In version 1.0.0, the api returns a script that
// loses newlines.
guestConfiguration.setCustomizationScript(customizationScript);
task = client.updateGuestCustomizationOfVm(vm.getHref(), guestConfiguration);
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "updateGuestCustomizationOfVm", vm.getName(),
task));
}
}
public void updateVmWithIpAddressAllocationMode(Vm vm, final IpAddressAllocationMode ipAddressAllocationMode) {
Task task;
NetworkConnectionSection net = vm.getNetworkConnectionSection();
Builder builder = net.toBuilder();
builder.connections(Iterables.transform(net.getConnections(),
new Function<NetworkConnection, NetworkConnection>() {
@Override
public NetworkConnection apply(NetworkConnection arg0) {
return arg0.toBuilder().connected(true).ipAddressAllocationMode(ipAddressAllocationMode).build();
}
}));
task = client.updateNetworkConnectionOfVm(vm.getHref(), builder.build());
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "updateNetworkConnectionOfVm", vm.getName(),
task));
}
}
private NodeMetadata blockOnDeployAndPowerOnIfConfigured(InstantiateVAppTemplateOptions options, VApp vAppResponse,
Task task) {
Task task) {
if (options.shouldBlock()) {
if (!successTester.apply(task.getHref())) {
throw new RuntimeException(String.format("failed to %s %s: %s", "deploy and power on", vAppResponse
.getName(), task));
throw new RuntimeException(String.format("failed to %s %s: %s", "deploy and power on",
vAppResponse.getName(), task));
}
logger.debug("<< ready vApp(%s)", vAppResponse.getName());
}

View File

@ -36,8 +36,9 @@ import org.jclouds.vcloud.domain.ovf.ResourceAllocation;
import org.jclouds.vcloud.domain.ovf.ResourceType;
import org.jclouds.vcloud.domain.ovf.VCloudNetworkAdapter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
*
@ -77,7 +78,7 @@ public class VCloudComputeUtils {
public static Credentials getCredentialsFrom(Vm vm) {
String user = "root";
if (vm.getOperatingSystemSection() != null && vm.getOperatingSystemSection().getDescription() != null
&& vm.getOperatingSystemSection().getDescription().indexOf("Windows") >= 0)
&& vm.getOperatingSystemSection().getDescription().indexOf("Windows") >= 0)
user = "Administrator";
String password = null;
if (vm.getGuestCustomizationSection() != null)
@ -85,34 +86,35 @@ public class VCloudComputeUtils {
return new Credentials(user, password);
}
public static Set<String> getPublicIpsFromVApp(VApp vApp) {
Set<String> ips = Sets.newLinkedHashSet();
public static Set<String> getIpsFromVApp(VApp vApp) {
// TODO make this work with composite vApps
if (vApp.getChildren().size() == 0)
return ips;
return ImmutableSet.of();
Builder<String> ips = ImmutableSet.<String> builder();
Vm vm = Iterables.get(vApp.getChildren(), 0);
// TODO: figure out how to differentiate public from private ip addresses
// assumption is that we'll do this from the network object, which may have
// enough data to tell whether or not it is a public network without string
// parsing. At worst, we could have properties set per cloud provider to
// declare the networks which are public, then check against these in
// parsing. At worst, we could have properties set per cloud provider to
// declare the networks which are public, then check against these in
// networkconnection.getNetwork
if (vm.getNetworkConnectionSection() != null) {
for (NetworkConnection connection : vm.getNetworkConnectionSection().getConnections())
ips.add(connection.getIpAddress());
for (NetworkConnection connection : vm.getNetworkConnectionSection().getConnections()) {
if (connection.getIpAddress() != null)
ips.add(connection.getIpAddress());
if (connection.getExternalIpAddress() != null)
ips.add(connection.getExternalIpAddress());
}
} else {
for (ResourceAllocation net : filter(vm.getVirtualHardwareSection().getResourceAllocations(),
resourceType(ResourceType.ETHERNET_ADAPTER))) {
resourceType(ResourceType.ETHERNET_ADAPTER))) {
if (net instanceof VCloudNetworkAdapter) {
VCloudNetworkAdapter vNet = VCloudNetworkAdapter.class.cast(net);
ips.add(vNet.getIpAddress());
if (vNet.getIpAddress() != null)
ips.add(vNet.getIpAddress());
}
}
}
return ips;
}
public static Set<String> getPrivateIpsFromVApp(VApp vApp) {
return Sets.newLinkedHashSet();
return ips.build();
}
}

View File

@ -30,7 +30,7 @@ import javax.inject.Singleton;
import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.AsyncClientFactory;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.vcloud.VCloudAsyncClient;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudLoginAsyncClient;
@ -78,7 +78,7 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
@Singleton
protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final VCloudLoginAsyncClient login) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<VCloudSession>(authException, seconds,
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<VCloudSession>(authException, seconds,
new Supplier<VCloudSession>() {
@Override

View File

@ -29,6 +29,67 @@ import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
* @author Adrian Cole
*/
public class NetworkConnection {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private String network;
private int networkConnectionIndex;
private String ipAddress;
private String externalIpAddress;
private boolean connected;
private String MACAddress;
private IpAddressAllocationMode ipAddressAllocationMode;
public Builder network(String network) {
this.network = network;
return this;
}
public Builder networkConnectionIndex(int networkConnectionIndex) {
this.networkConnectionIndex = networkConnectionIndex;
return this;
}
public Builder ipAddress(String ipAddress) {
this.ipAddress = ipAddress;
return this;
}
public Builder externalIpAddress(String externalIpAddress) {
this.externalIpAddress = externalIpAddress;
return this;
}
public Builder connected(boolean connected) {
this.connected = connected;
return this;
}
public Builder MACAddress(String MACAddress) {
this.MACAddress = MACAddress;
return this;
}
public Builder ipAddressAllocationMode(IpAddressAllocationMode ipAddressAllocationMode) {
this.ipAddressAllocationMode = ipAddressAllocationMode;
return this;
}
public NetworkConnection build() {
return new NetworkConnection(network, networkConnectionIndex, ipAddress, externalIpAddress, connected,
MACAddress, ipAddressAllocationMode);
}
public static Builder fromNetworkConnection(NetworkConnection in) {
return new Builder().network(in.getNetwork()).networkConnectionIndex(in.getNetworkConnectionIndex())
.ipAddress(in.getIpAddress()).externalIpAddress(in.getExternalIpAddress()).connected(in.isConnected())
.MACAddress(in.getMACAddress()).ipAddressAllocationMode(in.getIpAddressAllocationMode());
}
}
private final String network;
private final int networkConnectionIndex;
@Nullable
@ -41,8 +102,8 @@ public class NetworkConnection {
private final IpAddressAllocationMode ipAddressAllocationMode;
public NetworkConnection(String network, int networkConnectionIndex, @Nullable String ipAddress,
@Nullable String externalIpAddress, boolean connected, @Nullable String MACAddress,
IpAddressAllocationMode ipAddressAllocationMode) {
@Nullable String externalIpAddress, boolean connected, @Nullable String MACAddress,
IpAddressAllocationMode ipAddressAllocationMode) {
this.network = network;
this.networkConnectionIndex = networkConnectionIndex;
this.ipAddress = ipAddress;
@ -162,11 +223,15 @@ public class NetworkConnection {
return true;
}
public Builder toBuilder() {
return Builder.fromNetworkConnection(this);
}
@Override
public String toString() {
return "[network=" + network + ", connected=" + connected + ", ipAddress=" + ipAddress + ", externalIpAddress="
+ externalIpAddress + ", networkConnectionIndex=" + networkConnectionIndex
+ ", ipAddressAllocationMode=" + ipAddressAllocationMode + ", MACAddress=" + MACAddress + "]";
+ externalIpAddress + ", networkConnectionIndex=" + networkConnectionIndex + ", ipAddressAllocationMode="
+ ipAddressAllocationMode + ", MACAddress=" + MACAddress + "]";
}
}

View File

@ -24,8 +24,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Set;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableSet;
/**
* The NetworkConnectionSection element specifies how a Vm is connected to a vApp network. It
@ -36,20 +35,73 @@ import com.google.common.collect.Sets;
* values specified in the NetworkConnectionSection override those specified in the NetworkSection.
*/
public class NetworkConnectionSection {
public static Builder builder() {
return new Builder();
}
public static class Builder {
protected String type;
protected URI href;
protected String info;
protected Integer primaryNetworkConnectionIndex;
protected Set<NetworkConnection> connections = ImmutableSet.of();
protected ReferenceType edit;
public Builder type(String type) {
this.type = type;
return this;
}
public Builder href(URI href) {
this.href = href;
return this;
}
public Builder info(String info) {
this.info = info;
return this;
}
public Builder primaryNetworkConnectionIndex(Integer primaryNetworkConnectionIndex) {
this.primaryNetworkConnectionIndex = primaryNetworkConnectionIndex;
return this;
}
public Builder connections(Iterable<? extends NetworkConnection> connections) {
this.connections = ImmutableSet.copyOf(checkNotNull(connections, "connections"));
return this;
}
public Builder edit(ReferenceType edit) {
this.edit = edit;
return this;
}
public NetworkConnectionSection build() {
return new NetworkConnectionSection(type, href, info, primaryNetworkConnectionIndex, connections, edit);
}
public static Builder fromNetworkConnectionSection(NetworkConnectionSection in) {
return new Builder().type(in.getType()).href(in.getHref()).info(in.getInfo())
.primaryNetworkConnectionIndex(in.getPrimaryNetworkConnectionIndex()).connections(in.getConnections())
.edit(in.getEdit());
}
}
protected final String type;
protected final URI href;
protected final String info;
protected final Integer primaryNetworkConnectionIndex;
protected final Set<NetworkConnection> connections = Sets.newLinkedHashSet();
protected final Set<NetworkConnection> connections;
protected final ReferenceType edit;
public NetworkConnectionSection(String type, URI href, String info, Integer primaryNetworkConnectionIndex,
Iterable<NetworkConnection> connections, ReferenceType edit) {
Iterable<NetworkConnection> connections, ReferenceType edit) {
this.type = type;
this.href = href;
this.info = info;
this.primaryNetworkConnectionIndex = primaryNetworkConnectionIndex;
Iterables.addAll(this.connections, checkNotNull(connections, "connections"));
this.connections = ImmutableSet.copyOf(checkNotNull(connections, "connections"));
this.edit = edit;
}
@ -109,7 +161,7 @@ public class NetworkConnectionSection {
result = prime * result + ((href == null) ? 0 : href.hashCode());
result = prime * result + ((info == null) ? 0 : info.hashCode());
result = prime * result
+ ((primaryNetworkConnectionIndex == null) ? 0 : primaryNetworkConnectionIndex.hashCode());
+ ((primaryNetworkConnectionIndex == null) ? 0 : primaryNetworkConnectionIndex.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@ -156,10 +208,14 @@ public class NetworkConnectionSection {
return true;
}
public Builder toBuilder() {
return Builder.fromNetworkConnectionSection(this);
}
@Override
public String toString() {
return "[href=" + href + ", connections=" + connections + ", primaryNetworkConnectionIndex="
+ primaryNetworkConnectionIndex + "]";
+ primaryNetworkConnectionIndex + "]";
}
}

View File

@ -56,9 +56,9 @@ public class GuestCustomizationSectionHandler extends ParseSax.HandlerWithResult
public GuestCustomizationSection getResult() {
GuestCustomizationSection system = new GuestCustomizationSection(guest.getType(), guest.getHref(), info, enabled,
changeSid, virtualMachineId, joinDomainEnabled, useOrgSettings, domainName, domainUserName,
domainUserPassword, adminPasswordEnabled, adminPasswordAuto, adminPassword, resetPasswordRequired,
customizationScript, computerName, edit);
changeSid, virtualMachineId, joinDomainEnabled, useOrgSettings, domainName, domainUserName,
domainUserPassword, adminPasswordEnabled, adminPasswordAuto, adminPassword, resetPasswordRequired,
customizationScript, computerName, edit);
this.guest = null;
this.info = null;
this.edit = null;
@ -81,6 +81,7 @@ public class GuestCustomizationSectionHandler extends ParseSax.HandlerWithResult
public void startElement(String uri, String localName, String qName, Attributes attrs) {
Map<String, String> attributes = cleanseAttributes(attrs);
this.currentText = new StringBuilder();
if (qName.endsWith("GuestCustomizationSection")) {
guest = newReferenceType(attributes);
} else if (qName.endsWith("Link") && "edit".equals(attributes.get("rel"))) {
@ -119,8 +120,7 @@ public class GuestCustomizationSectionHandler extends ParseSax.HandlerWithResult
} else if (qName.endsWith("CustomizationScript")) {
this.customizationScript = currentOrNull();
if (this.customizationScript != null)
customizationScript = customizationScript.replace("&lt;", "<").replace(">", "&gt;").replace("&quot;", "\"")
.replace("&apos;", "'").replace("&#13;", "\r\n").replace("&#13;", "\n").replace("&amp;", "&");
customizationScript = customizationScript.replace("&gt;", ">");
} else if (qName.endsWith("ComputerName")) {
this.computerName = currentOrNull();
} else if (qName.endsWith("Name")) {
@ -134,7 +134,7 @@ public class GuestCustomizationSectionHandler extends ParseSax.HandlerWithResult
}
protected String currentOrNull() {
String returnVal = currentText.toString().trim();
String returnVal = currentText.toString();
return returnVal.equals("") ? null : returnVal;
}
}

View File

@ -22,6 +22,7 @@ package org.jclouds.vcloud;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.get;
import static com.google.common.collect.Iterables.getOnlyElement;
import static org.jclouds.crypto.CryptoStreams.base64;
import static org.testng.Assert.assertEquals;
import java.util.Properties;
@ -31,26 +32,31 @@ import org.jclouds.Constants;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshClient.Factory;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.compute.options.VCloudTemplateOptions;
import org.jclouds.vcloud.domain.Vm;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Guice;
import com.google.inject.Module;
/**
* This tests that we can use guest customization as an alternative to bootstrapping with ssh. There
* are a few advangroupes to this, including the fact that it can work inside google appengine where
* are a few advantages to this, including the fact that it can work inside google appengine where
* network sockets (ssh:22) are prohibited.
*
* @author Adrian Cole
@ -58,7 +64,7 @@ import com.google.inject.Module;
@Test(groups = "live", enabled = true, sequential = true)
public class VCloudGuestCustomizationLiveTest {
public static final String PARSE_VMTOOLSD = "vmtoolsd --cmd=\"info-get guestinfo.ovfenv\" |grep vCloud_CustomizationInfo|sed 's/.*value=\"\\(.*\\)\".*/\\1/g'|base64 -d";
public static final String PARSE_VMTOOLSD = "vmtoolsd --cmd=\"info-get guestinfo.ovfenv\" |grep vCloud_CustomizationInfo|sed 's/.*value=\"\\(.*\\)\".*/\\1/g'";
protected ComputeServiceContext context;
protected ComputeService client;
@ -71,6 +77,8 @@ public class VCloudGuestCustomizationLiveTest {
protected String endpoint;
protected String apiversion;
protected NodeMetadata node;
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = System.getProperty("test." + provider + ".credential");
@ -96,51 +104,89 @@ public class VCloudGuestCustomizationLiveTest {
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
client = new ComputeServiceContextFactory().createContext(provider,
client = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getComputeService();
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 60, 1, TimeUnit.SECONDS);
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 300, 1, TimeUnit.SECONDS);
sshFactory = Guice.createInjector(getSshModule()).getInstance(Factory.class);
}
protected Properties setupRestProperties() {
return RestContextFactory.getPropertiesFromResource("/rest.properties");
}
protected JschSshClientModule getSshModule() {
return new JschSshClientModule();
}
// make sure the script has a lot of screwy characters, knowing our parser throws-out \r
private String iLoveAscii = "I '\"love\"' {asc|!}*&";
String script = "cat > /root/foo.txt<<EOF\n" + iLoveAscii + "\nEOF\n";
@Test
public void testExtendedOptionsWithCustomizationScript() throws Exception {
String group = "customize";
String script = "cat > /root/foo.txt<<EOF\nI love candy\nEOF\n";
TemplateOptions options = client.templateOptions();
options.as(VCloudTemplateOptions.class).customizationScript(script);
node = getOnlyElement(client.createNodesInGroup(group, 1, options));
NodeMetadata node = null;
Vm vm = Iterables.get(
((VCloudClient) client.getContext().getProviderSpecificContext().getApi()).getVApp(node.getUri())
.getChildren(), 0);
String apiOutput = vm.getGuestCustomizationSection().getCustomizationScript();
checkApiOutput(apiOutput);
IPSocket socket = getSocket(node);
System.out.printf("%s:%s@%s", node.getCredentials().identity, node.getCredentials().credential, socket);
assert socketTester.apply(socket) : socket;
SshClient ssh = sshFactory.create(socket, node.getCredentials());
try {
node = getOnlyElement(client.createNodesInGroup(group, 1, options));
IPSocket socket = new IPSocket(get(node.getPublicAddresses(), 0), 22);
assert socketTester.apply(socket);
SshClient ssh = sshFactory.create(socket, node.getCredentials());
try {
ssh.connect();
assertEquals(ssh.exec(PARSE_VMTOOLSD).getOutput(), script.replaceAll("\n", "\r\n"));
assertEquals(ssh.exec("cat /root/foo.txt").getOutput().trim(), "I love candy");
} finally {
if (ssh != null)
ssh.disconnect();
}
ssh.connect();
ExecResponse vmTools = ssh.exec(PARSE_VMTOOLSD);
System.out.println(vmTools);
String fooTxt = ssh.exec("cat /root/foo.txt").getOutput();
String decodedVmToolsOutput = new String(base64(vmTools.getOutput().trim()));
checkVmOutput(fooTxt, decodedVmToolsOutput);
} finally {
if (node != null)
client.destroyNode(node.getId());
if (ssh != null)
ssh.disconnect();
}
}
protected void checkApiOutput(String apiOutput) {
checkApiOutput1_0_1(apiOutput);
}
protected void checkApiOutput1_0_1(String apiOutput) {
// in 1.0.1, vcloud director seems to pass through characters via api flawlessly
assertEquals(apiOutput, script);
}
protected void checkApiOutput1_0_0(String apiOutput) {
// in 1.0.0, vcloud director seems to remove all newlines
assertEquals(apiOutput, script.replace("\n", ""));
}
protected void checkVmOutput(String fooTxtContentsMadeByVMwareTools, String decodedVMwareToolsOutput) {
// note that vmwaretools throws in \r characters when executing scripts
assertEquals(fooTxtContentsMadeByVMwareTools, iLoveAscii + "\r\n");
assertEquals(decodedVMwareToolsOutput, script);
}
@AfterTest
public void tearDown() {
if (node != null)
client.destroyNode(node.getId());
if (context != null)
context.close();
}
protected IPSocket getSocket(NodeMetadata node) {
return new IPSocket(get(node.getPublicAddresses(), 0), 22);
}
}

View File

@ -0,0 +1,86 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.binders;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.URI;
import java.util.Properties;
import org.jclouds.http.HttpRequest;
import org.jclouds.vcloud.VCloudPropertiesBuilder;
import org.jclouds.vcloud.domain.NetworkConnection;
import org.jclouds.vcloud.domain.NetworkConnectionSection;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Names;
/**
* Tests behavior of {@code BindNetworkConnectionSectionToXmlPayload}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class BindNetworkConnectionSectionToXmlPayloadTest {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
Properties props = new Properties();
Names.bindProperties(binder(), checkNotNull(new VCloudPropertiesBuilder(props).build(), "properties"));
}
});
public void testWithIpAllocationModeNONE() throws IOException {
@SuppressWarnings("rawtypes")
HttpRequest request = new HttpRequest.Builder().endpoint(URI.create("http://localhost/key")).method("GET")
.build();
BindNetworkConnectionSectionToXmlPayload binder = injector
.getInstance(BindNetworkConnectionSectionToXmlPayload.class);
binder.bindToRequest(
request,
NetworkConnectionSection
.builder()
.type("application/vnd.vmware.vcloud.networkConnectionSection+xml")
.info("Specifies the available VM network connections")
.href(URI.create("https://1.1.1.1/api/v1.0/vApp/vm-1/networkConnectionSection/"))
.connections(
ImmutableSet.<NetworkConnection> of(NetworkConnection.builder().network("none")
.ipAddressAllocationMode(IpAddressAllocationMode.NONE).build())).build());
assertEquals(request.getPayload().getContentMetadata().getContentType(),
"application/vnd.vmware.vcloud.networkConnectionSection+xml");
assertEquals(
request.getPayload().getRawContent(),
"<NetworkConnectionSection xmlns=\"http://www.vmware.com/vcloud/v1\" xmlns:ovf=\"http://schemas.dmtf.org/ovf/envelope/1\" href=\"https://1.1.1.1/api/v1.0/vApp/vm-1/networkConnectionSection/\" ovf:required=\"false\" type=\"application/vnd.vmware.vcloud.networkConnectionSection+xml\"><ovf:Info>Specifies the available VM network connections</ovf:Info><NetworkConnection network=\"none\"><NetworkConnectionIndex>0</NetworkConnectionIndex><IsConnected>false</IsConnected><IpAddressAllocationMode>NONE</IpAddressAllocationMode></NetworkConnection></NetworkConnectionSection>");
}
}

View File

@ -33,6 +33,9 @@ import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.VApp;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
*
*
@ -52,8 +55,8 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public void testAssignability() throws Exception {
@SuppressWarnings("unused")
RestContext<VCloudClient, VCloudAsyncClient> tmContext = new ComputeServiceContextFactory().createContext(
provider, identity, credential).getProviderSpecificContext();
RestContext<VCloudClient, VCloudAsyncClient> tmContext = new ComputeServiceContextFactory(setupRestProperties())
.createContext(provider, identity, credential).getProviderSpecificContext();
}
@Override
@ -64,8 +67,9 @@ public class VCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
assertEquals(node.getType(), ComputeType.NODE);
NodeMetadata allData = client.getNodeMetadata(node.getId());
System.out.println(allData.getHardware());
RestContext<VCloudClient, VCloudAsyncClient> tmContext = new ComputeServiceContextFactory().createContext(
provider, identity, credential).getProviderSpecificContext();
RestContext<VCloudClient, VCloudAsyncClient> tmContext = new ComputeServiceContextFactory(
setupRestProperties()).createContext(provider, identity, credential, ImmutableSet.<Module> of(),
setupProperties()).getProviderSpecificContext();
VApp vApp = tmContext.getApi().findVAppInOrgVDCNamed(null, null, allData.getName());
assertEquals(vApp.getName(), allData.getName());
}

View File

@ -0,0 +1,67 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.compute.functions;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.NoSuchElementException;
import java.util.Set;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.vcloud.domain.internal.ReferenceTypeImpl;
import org.testng.annotations.Test;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code FindLocationForResource}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class FindLocationForResourceTest {
public void testMatchWhenIdIsHref() {
Location location = new LocationBuilder().id("http://foo").description("description")
.scope(LocationScope.PROVIDER).build();
FindLocationForResource converter = new FindLocationForResource(
Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(location)));
assertEquals(converter.apply(new ReferenceTypeImpl("name", "type", URI.create("http://foo"))), location);
}
@Test(expectedExceptions = NoSuchElementException.class)
public void testGracefulWhenHrefIsntLocationId() {
FindLocationForResource converter = new FindLocationForResource(
Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(new LocationBuilder()
.id("http://bar").description("description").scope(LocationScope.PROVIDER).build())));
converter.apply(new ReferenceTypeImpl("name", "type", URI.create("http://foo")));
}
@Test(expectedExceptions = NoSuchElementException.class)
public void testGracefulWhenLocationIdIsntURI() {
FindLocationForResource converter = new FindLocationForResource(
Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(new LocationBuilder().id("1")
.description("description").scope(LocationScope.PROVIDER).build())));
converter.apply(new ReferenceTypeImpl("name", "type", URI.create("http://foo")));
}
}

View File

@ -0,0 +1,148 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.Set;
import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseSax.Factory;
import org.jclouds.http.functions.config.SaxParserModule;
import org.jclouds.vcloud.VCloudPropertiesBuilder;
import org.jclouds.vcloud.compute.config.CommonVCloudComputeServiceContextModule;
import org.jclouds.vcloud.domain.Status;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.xml.VAppHandler;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
/**
* Tests behavior of {@code VAppToNodeMetadata}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class VAppToNodeMetadataTest {
public Injector createInjectorWithLocation(final Location location) {
return Guice.createInjector(new SaxParserModule(), new AbstractModule() {
@Override
protected void configure() {
Properties props = new Properties();
Names.bindProperties(binder(), checkNotNull(new VCloudPropertiesBuilder(props).build(), "properties"));
bind(new TypeLiteral<Function<VApp, Hardware>>() {
}).to(new TypeLiteral<HardwareForVApp>() {
});
}
@SuppressWarnings("unused")
@Memoized
@Singleton
@Provides
Supplier<Set<? extends Location>> supplyLocations() {
return Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(location));
}
@SuppressWarnings("unused")
@Singleton
@Provides
Map<String, Credentials> supplyCreds() {
return Maps.newConcurrentMap();
}
@SuppressWarnings("unused")
@Singleton
@Provides
protected Map<Status, NodeState> provideVAppStatusToNodeState() {
return CommonVCloudComputeServiceContextModule.VAPPSTATUS_TO_NODESTATE;
}
});
}
public void testWhenVDCIsLocation() {
Location location = new LocationBuilder().id("https://1.1.1.1/api/v1.0/vdc/1").description("description")
.scope(LocationScope.PROVIDER).build();
Injector injector = createInjectorWithLocation(location);
InputStream is = getClass().getResourceAsStream("/vapp-pool.xml");
Factory factory = injector.getInstance(ParseSax.Factory.class);
VApp result = factory.create(injector.getInstance(VAppHandler.class)).parse(is);
VAppToNodeMetadata converter = injector.getInstance(VAppToNodeMetadata.class);
NodeMetadata node = converter.apply(result);
assertEquals(node.getLocation(), location);
assertEquals(node.getPrivateAddresses(), ImmutableSet.of("172.16.7.230"));
assertEquals(node.getPublicAddresses(), ImmutableSet.of());
}
public void testGracefulWhenNoIPs() {
Location location = new LocationBuilder().id("https://1.1.1.1/api/v1.0/vdc/1").description("description")
.scope(LocationScope.PROVIDER).build();
Injector injector = createInjectorWithLocation(location);
InputStream is = getClass().getResourceAsStream("/vapp-none.xml");
Factory factory = injector.getInstance(ParseSax.Factory.class);
VApp result = factory.create(injector.getInstance(VAppHandler.class)).parse(is);
VAppToNodeMetadata converter = injector.getInstance(VAppToNodeMetadata.class);
NodeMetadata node = converter.apply(result);
assertEquals(node.getLocation(), location);
assertEquals(node.getPrivateAddresses(), ImmutableSet.of());
assertEquals(node.getPublicAddresses(), ImmutableSet.of());
}
@Test(expectedExceptions = NoSuchElementException.class)
public void testGracefulWhenVDCIsNotLocation() {
Location location = new LocationBuilder().id("https://1.1.1.1/api/v1.0/vdc/11111").description("description")
.scope(LocationScope.PROVIDER).build();
Injector injector = createInjectorWithLocation(location);
InputStream is = getClass().getResourceAsStream("/vapp-pool.xml");
Factory factory = injector.getInstance(ParseSax.Factory.class);
VApp result = factory.create(injector.getInstance(VAppHandler.class)).parse(is);
VAppToNodeMetadata converter = injector.getInstance(VAppToNodeMetadata.class);
NodeMetadata node = converter.apply(result);
assertEquals(node.getLocation(), location);
}
}

View File

@ -24,12 +24,14 @@ import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.b
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.customizationScript;
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.inboundPorts;
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.installPrivateKey;
import static org.jclouds.vcloud.compute.options.VCloudTemplateOptions.Builder.ipAddressAllocationMode;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.io.Payloads;
import org.jclouds.vcloud.domain.network.IpAddressAllocationMode;
import org.testng.annotations.Test;
/**
@ -38,6 +40,18 @@ import org.testng.annotations.Test;
* @author Adrian Cole
*/
public class VCloudTemplateOptionsTest {
@Test
public void testipAddressAllocationMode() {
VCloudTemplateOptions options = new VCloudTemplateOptions();
options.ipAddressAllocationMode(IpAddressAllocationMode.NONE);
assertEquals(options.getIpAddressAllocationMode(), IpAddressAllocationMode.NONE);
}
@Test
public void testipAddressAllocationModeStatic() {
VCloudTemplateOptions options = ipAddressAllocationMode(IpAddressAllocationMode.NONE);
assertEquals(options.getIpAddressAllocationMode(), IpAddressAllocationMode.NONE);
}
public void testAs() {
TemplateOptions options = new VCloudTemplateOptions();
@ -50,6 +64,12 @@ public class VCloudTemplateOptionsTest {
options.customizationScript("");
}
@Test
public void testNullcustomizationScript() {
VCloudTemplateOptions options = new VCloudTemplateOptions();
assertEquals(options.getCustomizationScript(), null);
}
@Test
public void testcustomizationScript() {
VCloudTemplateOptions options = new VCloudTemplateOptions();
@ -57,12 +77,6 @@ public class VCloudTemplateOptionsTest {
assertEquals(options.getCustomizationScript(), "mykeypair");
}
@Test
public void testNullcustomizationScript() {
VCloudTemplateOptions options = new VCloudTemplateOptions();
assertEquals(options.getCustomizationScript(), null);
}
@Test
public void testcustomizationScriptStatic() {
VCloudTemplateOptions options = customizationScript("mykeypair");

View File

@ -43,7 +43,8 @@ public class GuestCustomizationSectionHandlerTest extends BaseHandlerTest {
public void testDefault() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/guestCustomization.xml");
GuestCustomizationSection result = factory.create(injector.getInstance(GuestCustomizationSectionHandler.class)).parse(is);
GuestCustomizationSection result = factory.create(injector.getInstance(GuestCustomizationSectionHandler.class))
.parse(is);
checkGuestCustomization(result);
@ -52,8 +53,8 @@ public class GuestCustomizationSectionHandlerTest extends BaseHandlerTest {
@Test(enabled = false)
public static void checkGuestCustomization(GuestCustomizationSection result) {
assertEquals(result.getType(), VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML);
assertEquals(result.getHref(), URI
.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vm-2087535248/guestCustomizationSection/"));
assertEquals(result.getHref(),
URI.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vm-2087535248/guestCustomizationSection/"));
assertEquals(result.getInfo(), "Specifies Guest OS Customization Settings");
assertEquals(result.isEnabled(), new Boolean(true));
assertEquals(result.shouldChangeSid(), new Boolean(false));
@ -67,11 +68,11 @@ public class GuestCustomizationSectionHandlerTest extends BaseHandlerTest {
assertEquals(result.isAdminPasswordAuto(), new Boolean(true));
assertEquals(result.getAdminPassword(), null);
assertEquals(result.isResetPasswordRequired(), new Boolean(false));
assertEquals(
result.getCustomizationScript(),
"#!/bin/bash if [[ $1 == \"postcustomization\" ]]; then echo \"post customization\" touch /root/.postcustomization ping www.redhat.com -c 1 sleep 30 # register with RHN /usr/sbin/rhnreg_ks --profilename vic_`hostname`_`dmidecode -s system-uuid` --activationkey=XXXXXXXXXXXX --force echo \"rhn registered\" # make hostname fully qualified to speed up sendmail start perl -i -pe \"s/`hostname`/`hostname`.victory.blk/g\" /etc/sysconfig/network rm /etc/ssh/*_key* service sshd restart echo \"completed\" fi");
assertEquals(result.getCustomizationScript(), "cat > /root/foo.txt<<EOF\nI '\"love\"' {asc|!}*&\nEOF\n");
assertEquals(result.getComputerName(), "RHEL5");
assertEquals(result.getEdit(), new ReferenceTypeImpl(null, VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML, URI
.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vm-2087535248/guestCustomizationSection/")));
assertEquals(
result.getEdit(),
new ReferenceTypeImpl(null, VCloudMediaType.GUESTCUSTOMIZATIONSECTION_XML, URI
.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vm-2087535248/guestCustomizationSection/")));
}
}

View File

@ -46,6 +46,7 @@ import com.google.inject.Injector;
*/
@Test(groups = "unit")
public class VAppHandlerTest {
public void testRhelOffStatic() {
InputStream is = getClass().getResourceAsStream("/vapp-rhel-off-static.xml");
Injector injector = Guice.createInjector(new SaxParserModule());
@ -55,8 +56,10 @@ public class VAppHandlerTest {
assertEquals(result.getHref(), URI.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vapp-607806320"));
assertEquals(result.getType(), "application/vnd.vmware.vcloud.vApp+xml");
assertEquals(result.getStatus(), Status.OFF);
assertEquals(result.getVDC(), new ReferenceTypeImpl(null, VCloudMediaType.VDC_XML, URI
.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1014839439")));
assertEquals(
result.getVDC(),
new ReferenceTypeImpl(null, VCloudMediaType.VDC_XML, URI
.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1014839439")));
assertEquals(result.getDescription(), null);
assertEquals(result.getTasks(), ImmutableList.of());
assert result.isOvfDescriptorUploaded();

View File

@ -12,7 +12,10 @@
<AdminPasswordEnabled>true</AdminPasswordEnabled>
<AdminPasswordAuto>true</AdminPasswordAuto>
<ResetPasswordRequired>false</ResetPasswordRequired>
<CustomizationScript>#!/bin/bash if [[ $1 == "postcustomization" ]]; then echo "post customization" touch /root/.postcustomization ping www.redhat.com -c 1 sleep 30 # register with RHN /usr/sbin/rhnreg_ks --profilename vic_`hostname`_`dmidecode -s system-uuid` --activationkey=XXXXXXXXXXXX --force echo "rhn registered" # make hostname fully qualified to speed up sendmail start perl -i -pe "s/`hostname`/`hostname`.victory.blk/g" /etc/sysconfig/network rm /etc/ssh/*_key* service sshd restart echo "completed" fi</CustomizationScript>
<CustomizationScript>cat &gt; /root/foo.txt&lt;&lt;EOF
I '"love"' {asc|!}*&amp;
EOF
</CustomizationScript>
<ComputerName>RHEL5</ComputerName>
<Link rel="edit"
type="application/vnd.vmware.vcloud.guestCustomizationSection+xml"

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2010 Cloud Conscious, LLC.
<info@cloudconscious.com>
====================================================================
Licensed 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.
====================================================================
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!--
For more configuration infromation and examples see the Apache
Log4j website: http://logging.apache.org/log4j/
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="SSHFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-ssh.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNCSSH" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="SSHFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<!-- ================ -->
<!-- Limit categories -->
<!-- ================ -->
<category name="org.jclouds">
<priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.ssh">
<priority value="DEBUG" />
<appender-ref ref="ASYNCSSH" />
</category>
<category name="jclouds.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<priority value="WARN" />
</root>
</log4j:configuration>

View File

@ -0,0 +1,237 @@
<VApp xmlns="http://www.vmware.com/vcloud/v1" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" deployed="true" status="4" name="customize-750" type="application/vnd.vmware.vcloud.vApp+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_VirtualSystemSettingData.xsd http://schemas.dmtf.org/ovf/envelope/1 http://schemas.dmtf.org/ovf/envelope/1/dsp8023_1.1.0.xsd http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_ResourceAllocationSettingData.xsd http://www.vmware.com/vcloud/v1 http://1.1.1.1/api/v1.0/schema/master.xsd">
<Link rel="power:powerOff" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/powerOff"/>
<Link rel="power:reboot" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/reboot"/>
<Link rel="power:reset" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/reset"/>
<Link rel="power:shutdown" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/shutdown"/>
<Link rel="power:suspend" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/suspend"/>
<Link rel="deploy" type="application/vnd.vmware.vcloud.deployVAppParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/action/deploy"/>
<Link rel="undeploy" type="application/vnd.vmware.vcloud.undeployVAppParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-98934665/action/undeploy"/>
<Link rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/controlAccess/"/>
<Link rel="controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/action/controlAccess"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vdc+xml" href="https://1.1.1.1/api/v1.0/vdc/1"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.vApp+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1"/>
<LeaseSettingsSection type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/leaseSettingsSection/" ovf:required="false">
<ovf:Info>Lease settings section</ovf:Info>
<Link rel="edit" type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/leaseSettingsSection/"/>
<DeploymentLeaseInSeconds>0</DeploymentLeaseInSeconds>
<StorageLeaseInSeconds>7776000</StorageLeaseInSeconds>
</LeaseSettingsSection>
<ovf:StartupSection xmlns:vcloud="http://www.vmware.com/vcloud/v1" vcloud:href="https://1.1.1.1/api/v1.0/vApp/vapp-1/startupSection/" vcloud:type="application/vnd.vmware.vcloud.startupSection+xml">
<ovf:Info>VApp startup section</ovf:Info>
<ovf:Item ovf:stopDelay="0" ovf:stopAction="powerOff" ovf:startDelay="0" ovf:startAction="powerOn" ovf:order="0" ovf:id="Centos-5.5_x64"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.startupSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/startupSection/"/>
</ovf:StartupSection>
<ovf:NetworkSection xmlns:vcloud="http://www.vmware.com/vcloud/v1" vcloud:href="https://1.1.1.1/api/v1.0/vApp/vapp-1/networkSection/" vcloud:type="application/vnd.vmware.vcloud.networkSection+xml">
<ovf:Info>The list of logical networks</ovf:Info>
<ovf:Network ovf:name="none">
<ovf:Description/>
</ovf:Network>
<ovf:Network ovf:name="none">
<ovf:Description>This is a special place-holder used for disconnected network interfaces.</ovf:Description>
</ovf:Network>
</ovf:NetworkSection>
<NetworkConfigSection type="application/vnd.vmware.vcloud.networkConfigSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/networkConfigSection/" ovf:required="false">
<ovf:Info>The configuration parameters for logical networks</ovf:Info>
<Link rel="edit" type="application/vnd.vmware.vcloud.networkConfigSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/networkConfigSection/"/>
<NetworkConfig networkName="none">
<Description/>
<Configuration>
<IpScope>
<IsInherited>true</IsInherited>
<Gateway>172.16.7.1</Gateway>
<Netmask>255.255.255.0</Netmask>
<Dns1>208.95.232.10</Dns1>
<Dns2>208.95.232.11</Dns2>
<IpRanges>
<IpRange>
<StartAddress>172.16.7.230</StartAddress>
<EndAddress>172.16.7.239</EndAddress>
</IpRange>
</IpRanges>
</IpScope>
<ParentNetwork type="application/vnd.vmware.vcloud.network+xml" name="Direct" href="https://1.1.1.1/api/v1.0/network/282371363"/>
<FenceMode>bridged</FenceMode>
<Features>
<DhcpService>
<IsEnabled>false</IsEnabled>
<DefaultLeaseTime>3600</DefaultLeaseTime>
<MaxLeaseTime>7200</MaxLeaseTime>
<IpRange>
<StartAddress>172.16.7.2</StartAddress>
<EndAddress>172.16.7.229</EndAddress>
</IpRange>
</DhcpService>
<FirewallService>
<IsEnabled>true</IsEnabled>
</FirewallService>
<NatService>
<IsEnabled>true</IsEnabled>
<NatType>ipTranslation</NatType>
<Policy>allowTraffic</Policy>
</NatService>
</Features>
</Configuration>
<IsDeployed>true</IsDeployed>
</NetworkConfig>
<NetworkConfig networkName="none">
<Description>This is a special place-holder used for disconnected network interfaces.</Description>
<Configuration>
<IpScope>
<IsInherited>false</IsInherited>
<Gateway>196.254.254.254</Gateway>
<Netmask>255.255.0.0</Netmask>
<Dns1>196.254.254.254</Dns1>
</IpScope>
<FenceMode>isolated</FenceMode>
</Configuration>
<IsDeployed>false</IsDeployed>
</NetworkConfig>
</NetworkConfigSection>
<Children>
<Vm deployed="true" status="4" name="Centos-5.5_x64" type="application/vnd.vmware.vcloud.vm+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1">
<Link rel="power:powerOff" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/powerOff"/>
<Link rel="power:reboot" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/reboot"/>
<Link rel="power:reset" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/reset"/>
<Link rel="power:shutdown" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/shutdown"/>
<Link rel="power:suspend" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/suspend"/>
<Link rel="undeploy" type="application/vnd.vmware.vcloud.undeployVAppParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/action/undeploy"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vApp+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.vm+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1"/>
<Link rel="screen:thumbnail" href="https://1.1.1.1/api/v1.0/vApp/vm-1/screen"/>
<Link rel="screen:acquireTicket" href="https://1.1.1.1/api/v1.0/vApp/vm-1/screen/action/acquireTicket"/>
<Link rel="media:insertMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/media/action/insertMedia"/>
<Link rel="media:ejectMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/media/action/ejectMedia"/>
<Description/>
<ovf:VirtualHardwareSection xmlns:vcloud="http://www.vmware.com/vcloud/v1" vcloud:href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/" vcloud:type="application/vnd.vmware.vcloud.virtualHardwareSection+xml">
<ovf:Info>Virtual hardware requirements</ovf:Info>
<ovf:System>
<vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
<vssd:InstanceID>0</vssd:InstanceID>
<vssd:VirtualSystemIdentifier>Centos-5.5_x64</vssd:VirtualSystemIdentifier>
<vssd:VirtualSystemType>vmx-07</vssd:VirtualSystemType>
</ovf:System>
<ovf:Item>
<rasd:Address>00:50:56:01:02:38</rasd:Address>
<rasd:AddressOnParent>0</rasd:AddressOnParent>
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
<rasd:Connection vcloud:primaryNetworkConnection="true" vcloud:ipAddressingMode="NONE">none</rasd:Connection>
<rasd:Description>PCNet32 ethernet adapter</rasd:Description>
<rasd:ElementName>Network adapter 0</rasd:ElementName>
<rasd:InstanceID>1</rasd:InstanceID>
<rasd:ResourceSubType>PCNet32</rasd:ResourceSubType>
<rasd:ResourceType>10</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:Address>0</rasd:Address>
<rasd:Description>SCSI Controller</rasd:Description>
<rasd:ElementName>SCSI Controller 0</rasd:ElementName>
<rasd:InstanceID>2</rasd:InstanceID>
<rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>
<rasd:ResourceType>6</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:AddressOnParent>0</rasd:AddressOnParent>
<rasd:Description>Hard disk</rasd:Description>
<rasd:ElementName>Hard disk 1</rasd:ElementName>
<rasd:HostResource vcloud:capacity="15360" vcloud:busType="6" vcloud:busSubType="lsilogic"/>
<rasd:InstanceID>2000</rasd:InstanceID>
<rasd:Parent>2</rasd:Parent>
<rasd:ResourceType>17</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:Address>0</rasd:Address>
<rasd:Description>IDE Controller</rasd:Description>
<rasd:ElementName>IDE Controller 0</rasd:ElementName>
<rasd:InstanceID>3</rasd:InstanceID>
<rasd:ResourceType>5</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:AddressOnParent>0</rasd:AddressOnParent>
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
<rasd:Description>CD/DVD Drive</rasd:Description>
<rasd:ElementName>CD/DVD Drive 1</rasd:ElementName>
<rasd:HostResource/>
<rasd:InstanceID>3002</rasd:InstanceID>
<rasd:Parent>3</rasd:Parent>
<rasd:ResourceType>15</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:AddressOnParent>0</rasd:AddressOnParent>
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
<rasd:Description>Floppy Drive</rasd:Description>
<rasd:ElementName>Floppy Drive 1</rasd:ElementName>
<rasd:HostResource/>
<rasd:InstanceID>8000</rasd:InstanceID>
<rasd:ResourceType>14</rasd:ResourceType>
</ovf:Item>
<ovf:Item vcloud:href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/cpu" vcloud:type="application/vnd.vmware.vcloud.rasdItem+xml">
<rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
<rasd:Description>Number of Virtual CPUs</rasd:Description>
<rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>
<rasd:InstanceID>4</rasd:InstanceID>
<rasd:Reservation>0</rasd:Reservation>
<rasd:ResourceType>3</rasd:ResourceType>
<rasd:VirtualQuantity>1</rasd:VirtualQuantity>
<rasd:Weight>0</rasd:Weight>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/cpu"/>
</ovf:Item>
<ovf:Item vcloud:href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/memory" vcloud:type="application/vnd.vmware.vcloud.rasdItem+xml">
<rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
<rasd:Description>Memory Size</rasd:Description>
<rasd:ElementName>2048 MB of memory</rasd:ElementName>
<rasd:InstanceID>5</rasd:InstanceID>
<rasd:Reservation>0</rasd:Reservation>
<rasd:ResourceType>4</rasd:ResourceType>
<rasd:VirtualQuantity>2048</rasd:VirtualQuantity>
<rasd:Weight>0</rasd:Weight>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/memory"/>
</ovf:Item>
<Link rel="edit" type="application/vnd.vmware.vcloud.virtualHardwareSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/cpu"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/cpu"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/memory"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/memory"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/disks"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/disks"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/media"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/networkCards"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/networkCards"/>
</ovf:VirtualHardwareSection>
<ovf:OperatingSystemSection xmlns:vcloud="http://www.vmware.com/vcloud/v1" xmlns:vmw="http://www.vmware.com/schema/ovf" ovf:id="80" vcloud:href="https://1.1.1.1/api/v1.0/vApp/vm-1/operatingSystemSection/" vcloud:type="application/vnd.vmware.vcloud.operatingSystemSection+xml" vmw:osType="rhel5_64Guest">
<ovf:Info>Specifies the operating system installed</ovf:Info>
<ovf:Description>Red Hat Enterprise Linux 5 (64-bit)</ovf:Description>
<Link rel="edit" type="application/vnd.vmware.vcloud.operatingSystemSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/operatingSystemSection/"/>
</ovf:OperatingSystemSection>
<NetworkConnectionSection type="application/vnd.vmware.vcloud.networkConnectionSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/networkConnectionSection/" ovf:required="false">
<ovf:Info>Specifies the available VM network connections</ovf:Info>
<PrimaryNetworkConnectionIndex>0</PrimaryNetworkConnectionIndex>
<NetworkConnection network="none">
<NetworkConnectionIndex>0</NetworkConnectionIndex>
<IsConnected>false</IsConnected>
<MACAddress>00:50:56:01:02:38</MACAddress>
<IpAddressAllocationMode>NONE</IpAddressAllocationMode>
</NetworkConnection>
<Link rel="edit" type="application/vnd.vmware.vcloud.networkConnectionSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/networkConnectionSection/"/>
</NetworkConnectionSection>
<GuestCustomizationSection type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/guestCustomizationSection/" ovf:required="false">
<ovf:Info>Specifies Guest OS Customization Settings</ovf:Info>
<Enabled>true</Enabled>
<ChangeSid>false</ChangeSid>
<VirtualMachineId>1</VirtualMachineId>
<JoinDomainEnabled>false</JoinDomainEnabled>
<UseOrgSettings>false</UseOrgSettings>
<AdminPasswordEnabled>true</AdminPasswordEnabled>
<AdminPasswordAuto>true</AdminPasswordAuto>
<AdminPassword>secret</AdminPassword>
<ResetPasswordRequired>false</ResetPasswordRequired>
<CustomizationScript>cat &gt; /root/foo.txt&lt;&lt;EOF
I love candy
EOF
</CustomizationScript>
<ComputerName>Centos-5.5_x64</ComputerName>
<Link rel="edit" type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/guestCustomizationSection/"/>
</GuestCustomizationSection>
<VAppScopedLocalId>Centos-5.5_x64</VAppScopedLocalId>
</Vm>
</Children>
</VApp>

View File

@ -0,0 +1,227 @@
<VApp xmlns="http://www.vmware.com/vcloud/v1" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" deployed="true" status="4" name="my-appExample" type="application/vnd.vmware.vcloud.vApp+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_VirtualSystemSettingData.xsd http://schemas.dmtf.org/ovf/envelope/1 http://schemas.dmtf.org/ovf/envelope/1/dsp8023_1.1.0.xsd http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_ResourceAllocationSettingData.xsd http://www.vmware.com/vcloud/v1 http://1.1.1.1/api/v1.0/schema/master.xsd">
<Link rel="power:powerOff" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/powerOff"/>
<Link rel="power:reboot" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/reboot"/>
<Link rel="power:reset" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/reset"/>
<Link rel="power:shutdown" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/shutdown"/>
<Link rel="power:suspend" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/power/action/suspend"/>
<Link rel="deploy" type="application/vnd.vmware.vcloud.deployVAppParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/action/deploy"/>
<Link rel="undeploy" type="application/vnd.vmware.vcloud.undeployVAppParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/action/undeploy"/>
<Link rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/controlAccess/"/>
<Link rel="controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/action/controlAccess"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vdc+xml" href="https://1.1.1.1/api/v1.0/vdc/1"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.vApp+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1"/>
<Description/>
<LeaseSettingsSection type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/leaseSettingsSection/" ovf:required="false">
<ovf:Info>Lease settings section</ovf:Info>
<Link rel="edit" type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/leaseSettingsSection/"/>
<DeploymentLeaseInSeconds>0</DeploymentLeaseInSeconds>
<StorageLeaseInSeconds>0</StorageLeaseInSeconds>
</LeaseSettingsSection>
<ovf:StartupSection xmlns:vcloud="http://www.vmware.com/vcloud/v1" vcloud:href="https://1.1.1.1/api/v1.0/vApp/vapp-1/startupSection/" vcloud:type="application/vnd.vmware.vcloud.startupSection+xml">
<ovf:Info>VApp startup section</ovf:Info>
<ovf:Item ovf:stopDelay="0" ovf:stopAction="powerOff" ovf:startDelay="0" ovf:startAction="powerOn" ovf:order="0" ovf:id="my-app"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.startupSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/startupSection/"/>
</ovf:StartupSection>
<ovf:NetworkSection xmlns:vcloud="http://www.vmware.com/vcloud/v1" vcloud:href="https://1.1.1.1/api/v1.0/vApp/vapp-1/networkSection/" vcloud:type="application/vnd.vmware.vcloud.networkSection+xml">
<ovf:Info>The list of logical networks</ovf:Info>
<ovf:Network ovf:name="Direct">
<ovf:Description/>
</ovf:Network>
</ovf:NetworkSection>
<NetworkConfigSection type="application/vnd.vmware.vcloud.networkConfigSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/networkConfigSection/" ovf:required="false">
<ovf:Info>The configuration parameters for logical networks</ovf:Info>
<Link rel="edit" type="application/vnd.vmware.vcloud.networkConfigSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1/networkConfigSection/"/>
<NetworkConfig networkName="Direct">
<Description/>
<Configuration>
<IpScope>
<IsInherited>true</IsInherited>
<Gateway>172.16.7.1</Gateway>
<Netmask>255.255.255.0</Netmask>
<Dns1>1.1.1.2</Dns1>
<Dns2>1.1.1.3</Dns2>
<IpRanges>
<IpRange>
<StartAddress>172.16.7.230</StartAddress>
<EndAddress>172.16.7.239</EndAddress>
</IpRange>
</IpRanges>
</IpScope>
<ParentNetwork type="application/vnd.vmware.vcloud.network+xml" name="Direct" href="https://1.1.1.1/api/v1.0/network/282371363"/>
<FenceMode>bridged</FenceMode>
<Features>
<DhcpService>
<IsEnabled>false</IsEnabled>
<DefaultLeaseTime>3600</DefaultLeaseTime>
<MaxLeaseTime>7200</MaxLeaseTime>
<IpRange>
<StartAddress>172.16.7.2</StartAddress>
<EndAddress>172.16.7.229</EndAddress>
</IpRange>
</DhcpService>
<FirewallService>
<IsEnabled>true</IsEnabled>
</FirewallService>
<NatService>
<IsEnabled>true</IsEnabled>
<NatType>ipTranslation</NatType>
<Policy>allowTraffic</Policy>
<NatRule>
<OneToOneVmRule>
<MappingMode>automatic</MappingMode>
<VAppScopedVmId>100c208b-4f43-40bb-98d6-a046f6e48c3a</VAppScopedVmId>
<VmNicId>0</VmNicId>
</OneToOneVmRule>
</NatRule>
</NatService>
</Features>
</Configuration>
<IsDeployed>true</IsDeployed>
</NetworkConfig>
</NetworkConfigSection>
<Children>
<Vm deployed="true" status="4" name="my-app" type="application/vnd.vmware.vcloud.vm+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1">
<Link rel="power:powerOff" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/powerOff"/>
<Link rel="power:reboot" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/reboot"/>
<Link rel="power:reset" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/reset"/>
<Link rel="power:shutdown" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/shutdown"/>
<Link rel="power:suspend" href="https://1.1.1.1/api/v1.0/vApp/vm-1/power/action/suspend"/>
<Link rel="undeploy" type="application/vnd.vmware.vcloud.undeployVAppParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/action/undeploy"/>
<Link rel="up" type="application/vnd.vmware.vcloud.vApp+xml" href="https://1.1.1.1/api/v1.0/vApp/vapp-1"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.vm+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1"/>
<Link rel="screen:thumbnail" href="https://1.1.1.1/api/v1.0/vApp/vm-1/screen"/>
<Link rel="screen:acquireTicket" href="https://1.1.1.1/api/v1.0/vApp/vm-1/screen/action/acquireTicket"/>
<Link rel="media:insertMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/media/action/insertMedia"/>
<Link rel="media:ejectMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/media/action/ejectMedia"/>
<Description/>
<ovf:VirtualHardwareSection xmlns:vcloud="http://www.vmware.com/vcloud/v1" vcloud:href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/" vcloud:type="application/vnd.vmware.vcloud.virtualHardwareSection+xml">
<ovf:Info>Virtual hardware requirements</ovf:Info>
<ovf:System>
<vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
<vssd:InstanceID>0</vssd:InstanceID>
<vssd:VirtualSystemIdentifier>my-app</vssd:VirtualSystemIdentifier>
<vssd:VirtualSystemType>vmx-07</vssd:VirtualSystemType>
</ovf:System>
<ovf:Item>
<rasd:Address>00:50:56:01:02:33</rasd:Address>
<rasd:AddressOnParent>0</rasd:AddressOnParent>
<rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
<rasd:Connection vcloud:ipAddress="172.16.7.230" vcloud:primaryNetworkConnection="true" vcloud:ipAddressingMode="POOL">Direct</rasd:Connection>
<rasd:Description>PCNet32 ethernet adapter</rasd:Description>
<rasd:ElementName>Network adapter 0</rasd:ElementName>
<rasd:InstanceID>1</rasd:InstanceID>
<rasd:ResourceSubType>PCNet32</rasd:ResourceSubType>
<rasd:ResourceType>10</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:Address>0</rasd:Address>
<rasd:Description>SCSI Controller</rasd:Description>
<rasd:ElementName>SCSI Controller 0</rasd:ElementName>
<rasd:InstanceID>2</rasd:InstanceID>
<rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>
<rasd:ResourceType>6</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:AddressOnParent>0</rasd:AddressOnParent>
<rasd:Description>Hard disk</rasd:Description>
<rasd:ElementName>Hard disk 1</rasd:ElementName>
<rasd:HostResource vcloud:capacity="15360" vcloud:busType="6" vcloud:busSubType="lsilogic"/>
<rasd:InstanceID>2000</rasd:InstanceID>
<rasd:Parent>2</rasd:Parent>
<rasd:ResourceType>17</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:Address>0</rasd:Address>
<rasd:Description>IDE Controller</rasd:Description>
<rasd:ElementName>IDE Controller 0</rasd:ElementName>
<rasd:InstanceID>3</rasd:InstanceID>
<rasd:ResourceType>5</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:AddressOnParent>0</rasd:AddressOnParent>
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
<rasd:Description>CD/DVD Drive</rasd:Description>
<rasd:ElementName>CD/DVD Drive 1</rasd:ElementName>
<rasd:HostResource/>
<rasd:InstanceID>3002</rasd:InstanceID>
<rasd:Parent>3</rasd:Parent>
<rasd:ResourceType>15</rasd:ResourceType>
</ovf:Item>
<ovf:Item>
<rasd:AddressOnParent>0</rasd:AddressOnParent>
<rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
<rasd:Description>Floppy Drive</rasd:Description>
<rasd:ElementName>Floppy Drive 1</rasd:ElementName>
<rasd:HostResource/>
<rasd:InstanceID>8000</rasd:InstanceID>
<rasd:ResourceType>14</rasd:ResourceType>
</ovf:Item>
<ovf:Item vcloud:href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/cpu" vcloud:type="application/vnd.vmware.vcloud.rasdItem+xml">
<rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
<rasd:Description>Number of Virtual CPUs</rasd:Description>
<rasd:ElementName>1 virtual CPU(s)</rasd:ElementName>
<rasd:InstanceID>4</rasd:InstanceID>
<rasd:Reservation>0</rasd:Reservation>
<rasd:ResourceType>3</rasd:ResourceType>
<rasd:VirtualQuantity>1</rasd:VirtualQuantity>
<rasd:Weight>0</rasd:Weight>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/cpu"/>
</ovf:Item>
<ovf:Item vcloud:href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/memory" vcloud:type="application/vnd.vmware.vcloud.rasdItem+xml">
<rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
<rasd:Description>Memory Size</rasd:Description>
<rasd:ElementName>2048 MB of memory</rasd:ElementName>
<rasd:InstanceID>5</rasd:InstanceID>
<rasd:Reservation>0</rasd:Reservation>
<rasd:ResourceType>4</rasd:ResourceType>
<rasd:VirtualQuantity>2048</rasd:VirtualQuantity>
<rasd:Weight>0</rasd:Weight>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/memory"/>
</ovf:Item>
<Link rel="edit" type="application/vnd.vmware.vcloud.virtualHardwareSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/cpu"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/cpu"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/memory"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/memory"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/disks"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/disks"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/media"/>
<Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/networkCards"/>
<Link rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/virtualHardwareSection/networkCards"/>
</ovf:VirtualHardwareSection>
<ovf:OperatingSystemSection xmlns:vcloud="http://www.vmware.com/vcloud/v1" xmlns:vmw="http://www.vmware.com/schema/ovf" ovf:id="80" vcloud:href="https://1.1.1.1/api/v1.0/vApp/vm-1/operatingSystemSection/" vcloud:type="application/vnd.vmware.vcloud.operatingSystemSection+xml" vmw:osType="rhel5_64Guest">
<ovf:Info>Specifies the operating system installed</ovf:Info>
<ovf:Description>Red Hat Enterprise Linux 5 (64-bit)</ovf:Description>
<Link rel="edit" type="application/vnd.vmware.vcloud.operatingSystemSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/operatingSystemSection/"/>
</ovf:OperatingSystemSection>
<NetworkConnectionSection type="application/vnd.vmware.vcloud.networkConnectionSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/networkConnectionSection/" ovf:required="false">
<ovf:Info>Specifies the available VM network connections</ovf:Info>
<PrimaryNetworkConnectionIndex>0</PrimaryNetworkConnectionIndex>
<NetworkConnection network="Direct">
<NetworkConnectionIndex>0</NetworkConnectionIndex>
<IpAddress>172.16.7.230</IpAddress>
<IsConnected>true</IsConnected>
<MACAddress>00:50:56:01:02:33</MACAddress>
<IpAddressAllocationMode>POOL</IpAddressAllocationMode>
</NetworkConnection>
<Link rel="edit" type="application/vnd.vmware.vcloud.networkConnectionSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/networkConnectionSection/"/>
</NetworkConnectionSection>
<GuestCustomizationSection type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/guestCustomizationSection/" ovf:required="false">
<ovf:Info>Specifies Guest OS Customization Settings</ovf:Info>
<Enabled>true</Enabled>
<ChangeSid>false</ChangeSid>
<VirtualMachineId>1</VirtualMachineId>
<JoinDomainEnabled>false</JoinDomainEnabled>
<UseOrgSettings>false</UseOrgSettings>
<AdminPasswordEnabled>true</AdminPasswordEnabled>
<AdminPasswordAuto>true</AdminPasswordAuto>
<AdminPassword>Favor</AdminPassword>
<ResetPasswordRequired>false</ResetPasswordRequired>
<CustomizationScript/>
<ComputerName>my-app</ComputerName>
<Link rel="edit" type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" href="https://1.1.1.1/api/v1.0/vApp/vm-1/guestCustomizationSection/"/>
</GuestCustomizationSection>
<VAppScopedLocalId>100c208b-4f43-40bb-98d6-a046f6e48c3a</VAppScopedLocalId>
</Vm>
</Children>
</VApp>

View File

@ -310,7 +310,10 @@
<AdminPasswordEnabled>true</AdminPasswordEnabled>
<AdminPasswordAuto>true</AdminPasswordAuto>
<ResetPasswordRequired>false</ResetPasswordRequired>
<CustomizationScript>#!/bin/bash if [[ $1 == "postcustomization" ]]; then echo "post customization" touch /root/.postcustomization ping www.redhat.com -c 1 sleep 30 # register with RHN /usr/sbin/rhnreg_ks --profilename vic_`hostname`_`dmidecode -s system-uuid` --activationkey=XXXXXXXXXXXX --force echo "rhn registered" # make hostname fully qualified to speed up sendmail start perl -i -pe "s/`hostname`/`hostname`.victory.blk/g" /etc/sysconfig/network rm /etc/ssh/*_key* service sshd restart echo "completed" fi</CustomizationScript>
<CustomizationScript>cat &gt; /root/foo.txt&lt;&lt;EOF
I '"love"' {asc|!}*&amp;
EOF
</CustomizationScript>
<ComputerName>RHEL5</ComputerName>
<Link rel="edit"
type="application/vnd.vmware.vcloud.guestCustomizationSection+xml"

View File

@ -184,7 +184,10 @@
<AdminPasswordEnabled>true</AdminPasswordEnabled>
<AdminPasswordAuto>true</AdminPasswordAuto>
<ResetPasswordRequired>false</ResetPasswordRequired>
<CustomizationScript>#!/bin/bash if [[ $1 == "postcustomization" ]]; then echo "post customization" touch /root/.postcustomization ping www.redhat.com -c 1 sleep 30 # register with RHN /usr/sbin/rhnreg_ks --profilename vic_`hostname`_`dmidecode -s system-uuid` --activationkey=XXXXXXXXXXXX --force echo "rhn registered" # make hostname fully qualified to speed up sendmail start perl -i -pe "s/`hostname`/`hostname`.victory.blk/g" /etc/sysconfig/network rm /etc/ssh/*_key* service sshd restart echo "completed" fi</CustomizationScript>
<CustomizationScript>cat &gt; /root/foo.txt&lt;&lt;EOF
I '"love"' {asc|!}*&amp;
EOF
</CustomizationScript>
<ComputerName>RHEL5</ComputerName>
<Link rel="edit"
type="application/vnd.vmware.vcloud.guestCustomizationSection+xml"

View File

@ -30,7 +30,7 @@ import javax.inject.Singleton;
import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.AsyncClientFactory;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.vcloud.VCloudExpressAsyncClient;
import org.jclouds.vcloud.VCloudExpressClient;
import org.jclouds.vcloud.VCloudExpressLoginAsyncClient;
@ -78,7 +78,7 @@ public abstract class BaseVCloudExpressRestClientModule<S extends VCloudExpressC
@Singleton
protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final VCloudExpressLoginAsyncClient login) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<VCloudSession>(authException, seconds,
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<VCloudSession>(authException, seconds,
new Supplier<VCloudSession>() {
@Override

View File

@ -36,7 +36,7 @@ public class VCloudComputeServiceContextModuleTest {
for (Status state : EnumSet.allOf(Status.class).complementOf(
EnumSet.of(Status.PENDING_DESCRIPTOR, Status.PENDING_CONTENTS, Status.COPYING, Status.QUARANTINED,
Status.QUARANTINE_EXPIRED))) {
assert VCloudExpressComputeServiceContextModule.vAppStatusToNodeState.containsKey(state) : state;
assert VCloudExpressComputeServiceContextModule.VAPPSTATUS_TO_NODESTATE.containsKey(state) : state;
}
}

View File

@ -36,7 +36,7 @@ public class VCloudExpressComputeServiceContextModuleTest {
for (Status state : EnumSet.allOf(Status.class).complementOf(
EnumSet.of(Status.PENDING_DESCRIPTOR, Status.PENDING_CONTENTS, Status.COPYING, Status.QUARANTINED,
Status.QUARANTINE_EXPIRED))) {
assert VCloudExpressComputeServiceContextModule.vAppStatusToNodeState.containsKey(state) : state;
assert VCloudExpressComputeServiceContextModule.VAPPSTATUS_TO_NODESTATE.containsKey(state) : state;
}
}

View File

@ -32,7 +32,7 @@ import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.util.Strings2;
import org.jclouds.vcloud.config.BaseVCloudExpressRestClientModule;
import org.jclouds.vcloud.domain.ReferenceType;
@ -109,7 +109,7 @@ public abstract class TerremarkRestClientModule<S extends TerremarkVCloudClient,
@KeysList
protected Supplier<Map<String, ReferenceType>> provideOrgToKeysListCache(
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgNameToKeysListSupplier supplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, ReferenceType>>(authException,
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, ReferenceType>>(authException,
seconds, new Supplier<Map<String, ReferenceType>>() {
@Override
public Map<String, ReferenceType> get() {

View File

@ -42,18 +42,18 @@ import com.google.inject.Provides;
public abstract class CommonVCloudComputeServiceContextModule extends BaseComputeServiceContextModule {
@VisibleForTesting
static final Map<Status, NodeState> vAppStatusToNodeState = ImmutableMap.<Status, NodeState> builder().put(
Status.OFF, NodeState.SUSPENDED).put(Status.ON, NodeState.RUNNING).put(Status.RESOLVED, NodeState.PENDING)
.put(Status.ERROR, NodeState.ERROR).put(Status.UNRECOGNIZED, NodeState.UNRECOGNIZED).put(Status.DEPLOYED,
NodeState.PENDING).put(Status.INCONSISTENT, NodeState.PENDING).put(Status.UNKNOWN,
NodeState.UNRECOGNIZED).put(Status.MIXED, NodeState.PENDING).put(Status.WAITING_FOR_INPUT,
NodeState.PENDING).put(Status.SUSPENDED, NodeState.SUSPENDED).put(Status.UNRESOLVED,
NodeState.PENDING).build();
public static final Map<Status, NodeState> VAPPSTATUS_TO_NODESTATE = ImmutableMap.<Status, NodeState> builder()
.put(Status.OFF, NodeState.SUSPENDED).put(Status.ON, NodeState.RUNNING)
.put(Status.RESOLVED, NodeState.PENDING).put(Status.ERROR, NodeState.ERROR)
.put(Status.UNRECOGNIZED, NodeState.UNRECOGNIZED).put(Status.DEPLOYED, NodeState.PENDING)
.put(Status.INCONSISTENT, NodeState.PENDING).put(Status.UNKNOWN, NodeState.UNRECOGNIZED)
.put(Status.MIXED, NodeState.PENDING).put(Status.WAITING_FOR_INPUT, NodeState.PENDING)
.put(Status.SUSPENDED, NodeState.SUSPENDED).put(Status.UNRESOLVED, NodeState.PENDING).build();
@Singleton
@Provides
Map<Status, NodeState> provideVAppStatusToNodeState() {
return vAppStatusToNodeState;
protected Map<Status, NodeState> provideVAppStatusToNodeState() {
return VAPPSTATUS_TO_NODESTATE;
}
@Override

View File

@ -63,8 +63,7 @@ public class FindLocationForResource {
// link that only includes href and type.
if (URI.create(input.getId()).equals(resource.getHref()))
return input;
input = input.getParent();
} while (input.getParent() != null);
} while ((input = input.getParent()) != null);
}
throw new NoSuchElementException(String.format("resource: %s not found in locations: %s", resource, locations
.get()));

View File

@ -60,7 +60,7 @@ import org.jclouds.rest.AsyncClientFactory;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.vcloud.CommonVCloudAsyncClient;
import org.jclouds.vcloud.CommonVCloudClient;
import org.jclouds.vcloud.VCloudToken;
@ -146,7 +146,7 @@ public class CommonVCloudRestClientModule<S extends CommonVCloudClient, A extend
@org.jclouds.vcloud.endpoints.VDC
protected Supplier<Map<String, String>> provideVDCtoORG(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final Supplier<Map<String, ? extends Org>> orgToVDCSupplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, String>>(authException, seconds,
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, String>>(authException, seconds,
new Supplier<Map<String, String>>() {
@Override
public Map<String, String> get() {
@ -193,7 +193,7 @@ public class CommonVCloudRestClientModule<S extends CommonVCloudClient, A extend
@Singleton
protected Supplier<Map<String, ? extends Org>> provideOrgMapCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final OrgMapSupplier supplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, ? extends Org>>(authException,
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, ? extends Org>>(authException,
seconds, new Supplier<Map<String, ? extends Org>>() {
@Override
public Map<String, ? extends Org> get() {
@ -287,7 +287,7 @@ public class CommonVCloudRestClientModule<S extends CommonVCloudClient, A extend
@Singleton
protected Supplier<Map<String, ReferenceType>> provideVDCtoORG(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final OrgNameToOrgSupplier supplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, ReferenceType>>(authException,
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, ReferenceType>>(authException,
seconds, new Supplier<Map<String, ReferenceType>>() {
@Override
public Map<String, ReferenceType> get() {
@ -300,7 +300,7 @@ public class CommonVCloudRestClientModule<S extends CommonVCloudClient, A extend
@Singleton
protected Supplier<Map<URI, ? extends org.jclouds.vcloud.domain.VDC>> provideURIToVDC(
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final URItoVDC supplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<URI, ? extends org.jclouds.vcloud.domain.VDC>>(
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<URI, ? extends org.jclouds.vcloud.domain.VDC>>(
authException, seconds, new Supplier<Map<URI, ? extends org.jclouds.vcloud.domain.VDC>>() {
@Override
public Map<URI, ? extends org.jclouds.vcloud.domain.VDC> get() {
@ -463,7 +463,7 @@ public class CommonVCloudRestClientModule<S extends CommonVCloudClient, A extend
@Singleton
protected Supplier<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.Catalog>>> provideOrgCatalogItemMapSupplierCache(
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgCatalogSupplier supplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.Catalog>>>(
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.Catalog>>>(
authException, seconds,
new Supplier<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.Catalog>>>() {
@Override
@ -478,7 +478,7 @@ public class CommonVCloudRestClientModule<S extends CommonVCloudClient, A extend
@Singleton
protected Supplier<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.VDC>>> provideOrgVDCSupplierCache(
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.VDC>>>(
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.VDC>>>(
authException, seconds,
new Supplier<Map<String, Map<String, ? extends org.jclouds.vcloud.domain.VDC>>>() {
@Override
@ -561,7 +561,7 @@ public class CommonVCloudRestClientModule<S extends CommonVCloudClient, A extend
@Singleton
protected Supplier<Map<String, Map<String, Map<String, ? extends org.jclouds.vcloud.domain.CatalogItem>>>> provideOrgCatalogItemSupplierCache(
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgCatalogItemSupplier supplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, Map<String, Map<String, ? extends org.jclouds.vcloud.domain.CatalogItem>>>>(
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Map<String, Map<String, Map<String, ? extends org.jclouds.vcloud.domain.CatalogItem>>>>(
authException, seconds,
new Supplier<Map<String, Map<String, Map<String, ? extends org.jclouds.vcloud.domain.CatalogItem>>>>() {
@Override

View File

@ -117,43 +117,43 @@ public class VDCHandler extends ParseSax.HandlerWithResult<VDC> {
public void endElement(String uri, String name, String qName) {
taskHandler.endElement(uri, name, qName);
if (qName.equals("Task")) {
if (qName.endsWith("Task")) {
this.tasks.add(taskHandler.getResult());
} else if (qName.equals("Description")) {
} else if (qName.endsWith("Description")) {
description = currentOrNull();
} else if (qName.equals("AllocationModel")) {
} else if (qName.endsWith("AllocationModel")) {
allocationModel = AllocationModel.fromValue(currentOrNull());
} else if (qName.equals("Units")) {
} else if (qName.endsWith("Units")) {
units = currentOrNull();
} else if (qName.equals("Allocated")) {
} else if (qName.endsWith("Allocated")) {
allocated = Integer.parseInt(currentOrNull());
} else if (qName.equals("Used")) {
} else if (qName.endsWith("Used")) {
used = Integer.parseInt(currentOrNull());
} else if (qName.equals("Limit")) {
} else if (qName.endsWith("Limit")) {
limit = Integer.parseInt(currentOrNull());
} else if (qName.equals("Overhead")) {
} else if (qName.endsWith("Overhead")) {
overhead = Integer.parseInt(currentOrNull());
} else if (qName.equals("StorageCapacity")) {
} else if (qName.endsWith("StorageCapacity")) {
storageCapacity = new Capacity(units, allocated, limit, used, overhead);
resetCapacity();
} else if (qName.equals("Cpu")) {
} else if (qName.endsWith("Cpu")) {
cpuCapacity = new Capacity(units, allocated, limit, used, overhead);
resetCapacity();
} else if (qName.equals("Memory")) {
} else if (qName.endsWith("Memory")) {
memoryCapacity = new Capacity(units, allocated, limit, used, overhead);
resetCapacity();
} else if (qName.equals("DeployedVmsQuota")) {
} else if (qName.endsWith("DeployedVmsQuota")) {
vmQuota = (int) limit;
// vcloud express doesn't have the zero is unlimited rule
if (vmQuota == -1)
vmQuota = 0;
} else if (qName.equals("VmQuota")) {
} else if (qName.endsWith("VmQuota")) {
vmQuota = Integer.parseInt(currentOrNull());
} else if (qName.equals("NicQuota")) {
} else if (qName.endsWith("NicQuota")) {
nicQuota = Integer.parseInt(currentOrNull());
} else if (qName.equals("NetworkQuota")) {
} else if (qName.endsWith("NetworkQuota")) {
networkQuota = Integer.parseInt(currentOrNull());
} else if (qName.equals("IsEnabled")) {
} else if (qName.endsWith("IsEnabled")) {
isEnabled = Boolean.parseBoolean(currentOrNull());
}
currentText = new StringBuilder();

View File

@ -30,6 +30,7 @@ import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.Org;
@ -95,13 +96,13 @@ public abstract class CommonVCloudClientLiveTest<S extends CommonVCloudClient, A
VDC response = connection.getVDC(vdc.getHref());
for (ReferenceType resource : response.getAvailableNetworks().values()) {
if (resource.getType().equals(VCloudMediaType.NETWORK_XML)) {
try{
OrgNetwork item = connection.getNetwork(resource.getHref());
assertNotNull(item);
} catch (AuthorizationException e){
}
}
try {
OrgNetwork item = connection.getNetwork(resource.getHref());
assertNotNull(item);
} catch (AuthorizationException e) {
}
}
}
}
}
@ -206,11 +207,15 @@ public abstract class CommonVCloudClientLiveTest<S extends CommonVCloudClient, A
return overrides;
}
protected Properties setupRestProperties() {
return RestContextFactory.getPropertiesFromResource("/rest.properties");
}
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
context = new ComputeServiceContextFactory().createContext(provider,
context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
connection = context.getApi();

View File

@ -52,7 +52,7 @@ import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
import org.jclouds.json.Json;
import org.jclouds.location.config.LocationModule;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.scriptbuilder.domain.Statement;
import org.jclouds.scriptbuilder.domain.Statements;
import org.jclouds.ssh.SshClient;
@ -83,19 +83,20 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
bind(new TypeLiteral<Function<TemplateOptions, Statement>>() {
}).to(TemplateOptionsToStatement.class);
install(new FactoryModuleBuilder().implement(RunScriptOnNode.class, Names.named("direct"),
RunScriptOnNodeUsingSsh.class).implement(RunScriptOnNode.class, Names.named("blocking"),
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete.class).implement(RunScriptOnNode.class,
Names.named("nonblocking"), RunScriptOnNodeAsInitScriptUsingSsh.class).build(
RunScriptOnNodeFactoryImpl.Factory.class));
install(new FactoryModuleBuilder()
.implement(RunScriptOnNode.class, Names.named("direct"), RunScriptOnNodeUsingSsh.class)
.implement(RunScriptOnNode.class, Names.named("blocking"),
RunScriptOnNodeAsInitScriptUsingSshAndBlockUntilComplete.class)
.implement(RunScriptOnNode.class, Names.named("nonblocking"), RunScriptOnNodeAsInitScriptUsingSsh.class)
.build(RunScriptOnNodeFactoryImpl.Factory.class));
bind(RunScriptOnNode.Factory.class).to(RunScriptOnNodeFactoryImpl.class);
install(new FactoryModuleBuilder().implement(new TypeLiteral<Callable<Void>>() {
}, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.class).implement(
new TypeLiteral<Function<NodeMetadata, Void>>() {
}, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.class).build(
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory.class));
}, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.class)
.implement(new TypeLiteral<Function<NodeMetadata, Void>>() {
}, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.class)
.build(CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory.class));
install(new FactoryModuleBuilder().implement(new TypeLiteral<Callable<RunScriptOnNode>>() {
}, InitializeRunScriptOnNodeOrPlaceInBadMap.class).build(InitializeRunScriptOnNodeOrPlaceInBadMap.Factory.class));
@ -129,8 +130,8 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
checkNotNull(runScript, "runScript");
checkNotNull(options, "options");
return !options.shouldWrapInInitScript() ? factory.exec(node, runScript, options) : (options
.shouldBlockOnComplete() ? factory.backgroundAndBlockOnComplete(node, runScript, options) : factory
.background(node, runScript, options));
.shouldBlockOnComplete() ? factory.backgroundAndBlockOnComplete(node, runScript, options) : factory
.background(node, runScript, options));
}
@Override
@ -160,6 +161,15 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
return template.osFamily(UBUNTU).osVersionMatches("10.04").os64Bit(true);
}
/**
* The default options if none are provided.
*/
@Provides
@Named("DEFAULT")
protected TemplateOptions provideTemplateOptions(Injector injector, TemplateOptions options) {
return options;
}
/**
* supplies how the tag is encoded into the name. A string of hex characters is the last argument
* and tag is the first
@ -197,14 +207,14 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
@Singleton
@Memoized
protected Supplier<Set<? extends Image>> supplyImageCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final Supplier<Set<? extends Image>> imageSupplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Image>>(authException, seconds,
new Supplier<Set<? extends Image>>() {
@Override
public Set<? extends Image> get() {
return imageSupplier.get();
}
});
final Supplier<Set<? extends Image>> imageSupplier) {
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Image>>(authException, seconds,
new Supplier<Set<? extends Image>>() {
@Override
public Set<? extends Image> get() {
return imageSupplier.get();
}
});
}
@Provides
@ -231,14 +241,14 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
@Singleton
@Memoized
protected Supplier<Set<? extends Hardware>> supplySizeCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final Supplier<Set<? extends Hardware>> hardwareSupplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Hardware>>(authException, seconds,
new Supplier<Set<? extends Hardware>>() {
@Override
public Set<? extends Hardware> get() {
return hardwareSupplier.get();
}
});
final Supplier<Set<? extends Hardware>> hardwareSupplier) {
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Hardware>>(authException, seconds,
new Supplier<Set<? extends Hardware>>() {
@Override
public Set<? extends Hardware> get() {
return hardwareSupplier.get();
}
});
}
@Provides

View File

@ -116,9 +116,9 @@ public class TemplateBuilderImpl implements TemplateBuilder {
@Inject
protected TemplateBuilderImpl(@Memoized Supplier<Set<? extends Location>> locations,
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> hardwares,
Supplier<Location> defaultLocation2, Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider) {
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> hardwares,
Supplier<Location> defaultLocation2, @Named("DEFAULT") Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider) {
this.locations = locations;
this.images = images;
this.hardwares = hardwares;
@ -140,8 +140,8 @@ public class TemplateBuilderImpl implements TemplateBuilder {
boolean returnVal = true;
if (location != null && input.getLocation() != null)
returnVal = location.equals(input.getLocation()) || location.getParent() != null
&& location.getParent().equals(input.getLocation()) || location.getParent().getParent() != null
&& location.getParent().getParent().equals(input.getLocation());
&& location.getParent().equals(input.getLocation()) || location.getParent().getParent() != null
&& location.getParent().getParent().equals(input.getLocation());
return returnVal;
}
@ -215,7 +215,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
returnVal = false;
else
returnVal = input.getDescription().contains(osDescription)
|| input.getDescription().matches(osDescription);
|| input.getDescription().matches(osDescription);
}
return returnVal;
}
@ -329,8 +329,8 @@ public class TemplateBuilderImpl implements TemplateBuilder {
returnVal = false;
else
returnVal = input.getDescription().equals(imageDescription)
|| input.getDescription().contains(imageDescription)
|| input.getDescription().matches(imageDescription);
|| input.getDescription().contains(imageDescription)
|| input.getDescription().matches(imageDescription);
}
return returnVal;
}
@ -385,12 +385,12 @@ public class TemplateBuilderImpl implements TemplateBuilder {
}
};
private final Predicate<Hardware> hardwarePredicate = and(hardwareIdPredicate, locationPredicate,
hardwareCoresPredicate, hardwareRamPredicate);
hardwareCoresPredicate, hardwareRamPredicate);
static final Ordering<Hardware> DEFAULT_SIZE_ORDERING = new Ordering<Hardware>() {
public int compare(Hardware left, Hardware right) {
return ComparisonChain.start().compare(getCores(left), getCores(right)).compare(left.getRam(), right.getRam())
.compare(getSpace(left), getSpace(right)).result();
.compare(getSpace(left), getSpace(right)).result();
}
};
static final Ordering<Hardware> BY_CORES_ORDERING = new Ordering<Hardware>() {
@ -400,16 +400,16 @@ public class TemplateBuilderImpl implements TemplateBuilder {
};
static final Ordering<Image> DEFAULT_IMAGE_ORDERING = new Ordering<Image>() {
public int compare(Image left, Image right) {
return ComparisonChain.start().compare(left.getName(), right.getName(),
Ordering.<String> natural().nullsLast()).compare(left.getVersion(), right.getVersion(),
Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getName(),
right.getOperatingSystem().getName(),//
Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getVersion(),
right.getOperatingSystem().getVersion(),//
Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getDescription(),
right.getOperatingSystem().getDescription(),//
Ordering.<String> natural().nullsLast()).compare(left.getOperatingSystem().getArch(),
right.getOperatingSystem().getArch()).result();
return ComparisonChain.start()
.compare(left.getName(), right.getName(), Ordering.<String> natural().nullsLast())
.compare(left.getVersion(), right.getVersion(), Ordering.<String> natural().nullsLast())
.compare(left.getOperatingSystem().getName(), right.getOperatingSystem().getName(),//
Ordering.<String> natural().nullsLast())
.compare(left.getOperatingSystem().getVersion(), right.getOperatingSystem().getVersion(),//
Ordering.<String> natural().nullsLast())
.compare(left.getOperatingSystem().getDescription(), right.getOperatingSystem().getDescription(),//
Ordering.<String> natural().nullsLast())
.compare(left.getOperatingSystem().getArch(), right.getOperatingSystem().getArch()).result();
}
};
@ -549,7 +549,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
Iterable<? extends Image> supportedImages = filter(images, buildImagePredicate());
if (Iterables.size(supportedImages) == 0)
throw new NoSuchElementException(String.format(
"no image matched predicate %s images that didn't match below:\n%s", imagePredicate, images));
"no image matched predicate %s images that didn't match below:\n%s", imagePredicate, images));
Hardware hardware = resolveSize(hardwareSorter(), supportedImages);
Image image = resolveImage(hardware, supportedImages);
logger.debug("<< matched image(%s)", image);
@ -562,29 +562,29 @@ public class TemplateBuilderImpl implements TemplateBuilder {
Hardware hardware;
try {
Iterable<? extends Hardware> hardwaresThatAreCompatibleWithOurImages = filter(hardwaresl,
new Predicate<Hardware>() {
@Override
public boolean apply(final Hardware hardware) {
return Iterables.any(images, new Predicate<Image>() {
new Predicate<Hardware>() {
@Override
public boolean apply(final Hardware hardware) {
return Iterables.any(images, new Predicate<Image>() {
@Override
public boolean apply(Image input) {
return hardware.supportsImage().apply(input);
}
@Override
public boolean apply(Image input) {
return hardware.supportsImage().apply(input);
}
@Override
public String toString() {
return "hardware(" + hardware + ").supportsImage()";
}
@Override
public String toString() {
return "hardware(" + hardware + ").supportsImage()";
}
});
});
}
});
}
});
hardware = hardwareOrdering.max(filter(hardwaresThatAreCompatibleWithOurImages, hardwarePredicate));
} catch (NoSuchElementException exception) {
throw new NoSuchElementException("hardwares don't support any images: " + toString() + "\n" + hardwaresl
+ "\n" + images);
+ "\n" + images);
}
logger.debug("<< matched hardware(%s)", hardware);
return hardware;
@ -692,7 +692,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
// looks verbose, but explicit <Image> type needed for this to compile
// properly
Predicate<Image> imagePredicate = predicates.size() == 1 ? Iterables.<Predicate<Image>> get(predicates, 0)
: Predicates.<Image> and(predicates);
: Predicates.<Image> and(predicates);
return imagePredicate;
}
@ -840,9 +840,8 @@ public class TemplateBuilderImpl implements TemplateBuilder {
@VisibleForTesting
boolean nothingChangedExceptOptions() {
return osFamily == null && location == null && imageId == null && hardwareId == null && osName == null
&& osDescription == null && imageVersion == null && osVersion == null && osArch == null
&& os64Bit == null && imageName == null && imageDescription == null && minCores == 0 && minRam == 0
&& !biggest && !fastest;
&& osDescription == null && imageVersion == null && osVersion == null && osArch == null && os64Bit == null
&& imageName == null && imageDescription == null && minCores == 0 && minRam == 0 && !biggest && !fastest;
}
/**
@ -856,10 +855,10 @@ public class TemplateBuilderImpl implements TemplateBuilder {
@Override
public String toString() {
return "[biggest=" + biggest + ", fastest=" + fastest + ", imageName=" + imageName + ", imageDescription="
+ imageDescription + ", imageId=" + imageId + ", imageVersion=" + imageVersion + ", location="
+ location + ", minCores=" + minCores + ", minRam=" + minRam + ", osFamily=" + osFamily + ", osName="
+ osName + ", osDescription=" + osDescription + ", osVersion=" + osVersion + ", osArch=" + osArch
+ ", os64Bit=" + os64Bit + ", hardwareId=" + hardwareId + "]";
+ imageDescription + ", imageId=" + imageId + ", imageVersion=" + imageVersion + ", location=" + location
+ ", minCores=" + minCores + ", minRam=" + minRam + ", osFamily=" + osFamily + ", osName=" + osName
+ ", osDescription=" + osDescription + ", osVersion=" + osVersion + ", osArch=" + osArch + ", os64Bit="
+ os64Bit + ", hardwareId=" + hardwareId + "]";
}
@Override

View File

@ -35,8 +35,8 @@ import static org.jclouds.compute.options.TemplateOptions.Builder.blockOnComplet
import static org.jclouds.compute.options.TemplateOptions.Builder.overrideCredentialsWith;
import static org.jclouds.compute.predicates.NodePredicates.TERMINATED;
import static org.jclouds.compute.predicates.NodePredicates.all;
import static org.jclouds.compute.predicates.NodePredicates.runningWithTag;
import static org.jclouds.compute.predicates.NodePredicates.withTag;
import static org.jclouds.compute.predicates.NodePredicates.runningInGroup;
import static org.jclouds.compute.predicates.NodePredicates.inGroup;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@ -161,12 +161,12 @@ public abstract class BaseComputeServiceLiveTest {
if (context != null)
context.close();
Properties props = setupProperties();
context = new ComputeServiceContextFactory(getRestProperties()).createContext(provider, ImmutableSet.of(
context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, ImmutableSet.of(
new Log4JLoggingModule(), getSshModule()), props);
client = context.getComputeService();
}
protected Properties getRestProperties() {
protected Properties setupRestProperties() {
return RestContextFactory.getPropertiesFromResource("/rest.properties");
}
@ -182,7 +182,7 @@ public abstract class BaseComputeServiceLiveTest {
public void testCorrectAuthException() throws Exception {
ComputeServiceContext context = null;
try {
context = new ComputeServiceContextFactory().createContext(provider, "MOMMA", "MIA", ImmutableSet
context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, "MOMMA", "MIA", ImmutableSet
.<Module> of(new Log4JLoggingModule()));
context.getComputeService().listNodes();
} catch (AuthorizationException e) {
@ -207,7 +207,7 @@ public abstract class BaseComputeServiceLiveTest {
@Test(enabled = true, expectedExceptions = NoSuchElementException.class)
public void testCorrectExceptionRunningNodesNotFound() throws Exception {
client.runScriptOnNodesMatching(runningWithTag("zebras-are-awesome"), buildScript(new OperatingSystemBuilder()
client.runScriptOnNodesMatching(runningInGroup("zebras-are-awesome"), buildScript(new OperatingSystemBuilder()
.family(OsFamily.UBUNTU).description("ffoo").build()));
}
@ -215,23 +215,23 @@ public abstract class BaseComputeServiceLiveTest {
// starting this one alphabetically before create2nodes..
@Test(enabled = true, dependsOnMethods = { "testCompareSizes" })
public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
String tag = this.group + "r";
String group = this.group + "r";
try {
client.destroyNodesMatching(withTag(tag));
client.destroyNodesMatching(inGroup(group));
} catch (Exception e) {
}
TemplateOptions options = client.templateOptions().blockOnPort(22, 120);
try {
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, options);
Credentials good = nodes.iterator().next().getCredentials();
assert good.identity != null : nodes;
assert good.credential != null : nodes;
OperatingSystem os = get(nodes, 0).getOperatingSystem();
try {
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag, os, new Credentials(
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(group, os, new Credentials(
good.identity, "romeo"));
assert false : "shouldn't pass with a bad password\n" + responses;
} catch (RunScriptOnNodesException e) {
@ -239,17 +239,17 @@ public abstract class BaseComputeServiceLiveTest {
}
for (Entry<? extends NodeMetadata, ExecResponse> response : client.runScriptOnNodesMatching(
runningWithTag(tag), Statements.exec("echo hello"),
runningInGroup(group), Statements.exec("echo hello"),
overrideCredentialsWith(good).wrapInInitScript(false).runAsRoot(false)).entrySet())
assert response.getValue().getOutput().trim().equals("hello") : response.getKey() + ": "
+ response.getValue();
runScriptWithCreds(tag, os, good);
runScriptWithCreds(group, os, good);
checkNodes(nodes, tag);
checkNodes(nodes, group);
} finally {
client.destroyNodesMatching(withTag(tag));
client.destroyNodesMatching(inGroup(group));
}
}
@ -267,13 +267,13 @@ public abstract class BaseComputeServiceLiveTest {
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
public void testCreateTwoNodesWithRunScript() throws Exception {
try {
client.destroyNodesMatching(withTag(group));
client.destroyNodesMatching(inGroup(group));
} catch (NoSuchElementException e) {
}
refreshTemplate();
try {
nodes = newTreeSet(client.runNodesWithTag(group, 2, template));
nodes = newTreeSet(client.createNodesInGroup(group, 2, template));
} catch (RunNodesException e) {
nodes = newTreeSet(concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet()));
throw e;
@ -324,7 +324,7 @@ public abstract class BaseComputeServiceLiveTest {
public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired() throws Exception {
initializeContextAndClient();
refreshTemplate();
TreeSet<NodeMetadata> nodes = newTreeSet(client.runNodesWithTag(group, 1, template));
TreeSet<NodeMetadata> nodes = newTreeSet(client.createNodesInGroup(group, 1, template));
checkNodes(nodes, group);
NodeMetadata node = nodes.first();
this.nodes.add(node);
@ -340,21 +340,21 @@ public abstract class BaseComputeServiceLiveTest {
assert (context.getCredentialStore().get("node#" + node.getId()) != null) : "credentials for " + node.getId();
}
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String tag, OperatingSystem os,
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String group, OperatingSystem os,
Credentials creds) throws RunScriptOnNodesException {
try {
return client.runScriptOnNodesMatching(runningWithTag(tag), buildScript(os), overrideCredentialsWith(creds)
return client.runScriptOnNodesMatching(runningInGroup(group), buildScript(os), overrideCredentialsWith(creds)
.nameTask("runScriptWithCreds"));
} catch (SshException e) {
throw e;
}
}
protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String tag) throws IOException {
protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String group) throws IOException {
for (NodeMetadata node : nodes) {
assertNotNull(node.getProviderId());
assertNotNull(node.getTag());
assertEquals(node.getTag(), tag);
assertNotNull(node.getGroup());
assertEquals(node.getGroup(), group);
assertEquals(node.getState(), NodeState.RUNNING);
Credentials fromStore = context.getCredentialStore().get("node#" + node.getId());
assertEquals(fromStore, node.getCredentials());
@ -375,7 +375,7 @@ public abstract class BaseComputeServiceLiveTest {
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
public void testGet() throws Exception {
Map<String, ? extends NodeMetadata> metadataMap = newLinkedHashMap(uniqueIndex(filter(client
.listNodesDetailsMatching(all()), and(withTag(group), not(TERMINATED))),
.listNodesDetailsMatching(all()), and(inGroup(group), not(TERMINATED))),
new Function<NodeMetadata, String>() {
@Override
@ -388,7 +388,7 @@ public abstract class BaseComputeServiceLiveTest {
metadataMap.remove(node.getId());
NodeMetadata metadata = client.getNodeMetadata(node.getId());
assertEquals(metadata.getProviderId(), node.getProviderId());
assertEquals(metadata.getTag(), node.getTag());
assertEquals(metadata.getGroup(), node.getGroup());
assertLocationSameOrChild(metadata.getLocation(), template.getLocation());
checkImageIdMatchesTemplate(metadata);
checkOsMatchesTemplate(metadata);
@ -407,14 +407,14 @@ public abstract class BaseComputeServiceLiveTest {
@Test(enabled = true, dependsOnMethods = "testGet")
public void testReboot() throws Exception {
client.rebootNodesMatching(withTag(group));// TODO test
client.rebootNodesMatching(inGroup(group));// TODO test
// validation
testGet();
}
@Test(enabled = true, dependsOnMethods = "testReboot")
public void testSuspendResume() throws Exception {
client.suspendNodesMatching(withTag(group));
client.suspendNodesMatching(inGroup(group));
Set<? extends NodeMetadata> stoppedNodes = refreshNodes();
@ -430,7 +430,7 @@ public abstract class BaseComputeServiceLiveTest {
}) : stoppedNodes;
client.resumeNodesMatching(withTag(group));
client.resumeNodesMatching(inGroup(group));
testGet();
}
@ -467,24 +467,24 @@ public abstract class BaseComputeServiceLiveTest {
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
public void testDestroyNodes() {
int toDestroy = refreshNodes().size();
Set<? extends NodeMetadata> destroyed = client.destroyNodesMatching(withTag(group));
Set<? extends NodeMetadata> destroyed = client.destroyNodesMatching(inGroup(group));
assertEquals(toDestroy, destroyed.size());
for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), withTag(group))) {
for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), inGroup(group))) {
assert node.getState() == NodeState.TERMINATED : node;
assertEquals(context.getCredentialStore().get("node#" + node.getId()), null);
}
}
private Set<? extends NodeMetadata> refreshNodes() {
return filter(client.listNodesDetailsMatching(all()), and(withTag(group), not(TERMINATED)));
return filter(client.listNodesDetailsMatching(all()), and(inGroup(group), not(TERMINATED)));
}
@Test(enabled = true)
public void testCreateAndRunAService() throws Exception {
String tag = this.group + "s";
String group = this.group + "s";
try {
client.destroyNodesMatching(withTag(tag));
client.destroyNodesMatching(inGroup(group));
} catch (Exception e) {
}
@ -497,11 +497,11 @@ public abstract class BaseComputeServiceLiveTest {
RunScriptData.createScriptInstallAndStartJBoss(keyPair.get("public"), template.getImage()
.getOperatingSystem()));
try {
NodeMetadata node = getOnlyElement(client.runNodesWithTag(tag, 1, template));
NodeMetadata node = getOnlyElement(client.createNodesInGroup(group, 1, template));
checkHttpGet(node);
} finally {
client.destroyNodesMatching(withTag(tag));
client.destroyNodesMatching(inGroup(group));
}
}
@ -554,9 +554,9 @@ public abstract class BaseComputeServiceLiveTest {
}
public void testOptionToNotBlock() throws Exception {
String tag = this.group + "block";
String group = this.group + "block";
try {
client.destroyNodesMatching(withTag(tag));
client.destroyNodesMatching(inGroup(group));
} catch (Exception e) {
}
@ -564,13 +564,13 @@ public abstract class BaseComputeServiceLiveTest {
TemplateOptions options = client.templateOptions().blockUntilRunning(false).inboundPorts();
try {
long time = System.currentTimeMillis();
Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, options);
NodeMetadata node = getOnlyElement(nodes);
assert node.getState() != NodeState.RUNNING;
long duration = System.currentTimeMillis() - time;
assert duration < 30 * 1000 : "duration longer than 30 seconds!: " + duration / 1000;
} finally {
client.destroyNodesMatching(withTag(tag));
client.destroyNodesMatching(inGroup(group));
}
}

View File

@ -44,6 +44,7 @@ import org.jclouds.domain.LocationScope;
import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContextFactory;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
@ -91,10 +92,14 @@ public abstract class BaseTemplateBuilderLiveTest {
return overrides;
}
protected Properties setupRestProperties() {
return RestContextFactory.getPropertiesFromResource("/rest.properties");
}
@BeforeClass
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException {
setupCredentials();
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
context = new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, ImmutableSet
.<Module> of(new Log4JLoggingModule()), setupProperties());
}

View File

@ -21,7 +21,6 @@ package org.jclouds.concurrent;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
@ -31,6 +30,7 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.collect.ForwardingObject;
import com.google.common.util.concurrent.ExecutionList;
@ -44,54 +44,90 @@ import com.google.common.util.concurrent.ListenableFuture;
*/
@Beta
public class Futures {
@VisibleForTesting
static class CallGetAndRunExecutionList<T> implements Runnable {
private final Future<T> delegate;
private final ExecutionList executionList;
public static class FutureListener<T> {
private final Future<T> future;
final ExecutorService executor;
private final ExecutionList executionList = new ExecutionList();
private final AtomicBoolean hasListeners = new AtomicBoolean(false);
static <T> FutureListener<T> create(Future<T> future, ExecutorService executor) {
return new FutureListener<T>(future, executor);
public CallGetAndRunExecutionList(Future<T> delegate, ExecutionList executionList) {
this.delegate = checkNotNull(delegate, "delegate");
this.executionList = checkNotNull(executionList, "executionList");
}
private FutureListener(Future<T> future, ExecutorService executor) {
this.future = checkNotNull(future, "future");
this.executor = checkNotNull(executor, "executor");
@Override
public void run() {
try {
delegate.get();
} catch (InterruptedException e) {
// This thread was interrupted. This should never happen, so we
// throw an IllegalStateException.
Thread.currentThread().interrupt();
throw new IllegalStateException(String.format(
"interrupted calling get() on [%s], so could not run listeners", delegate), e);
} catch (Throwable e) {
// ExecutionException / CancellationException / RuntimeException
// The task is done, run the listeners.
}
executionList.run();
}
@Override
public String toString() {
return "[delegate=" + delegate + ", executionList=" + executionList + "]";
}
}
// Adapted from Guava
//
// * to allow us to enforce supply of an adapterExecutor
// note that this is done so that we can operate in Google AppEngine which
// restricts thread creation
// * to allow us to print debug info about what the delegate was doing
public static class FutureListener<T> {
final ExecutorService adapterExecutor;
// The execution list to hold our listeners.
private final ExecutionList executionList = new ExecutionList();
// This allows us to only start up a thread waiting on the delegate future
// when the first listener is added.
private final AtomicBoolean hasListeners = new AtomicBoolean(false);
// The delegate future.
private final Future<T> delegate;
static <T> FutureListener<T> create(Future<T> delegate, ExecutorService adapterExecutor) {
return new FutureListener<T>(delegate, adapterExecutor);
}
private FutureListener(Future<T> delegate, ExecutorService adapterExecutor) {
this.delegate = checkNotNull(delegate, "delegate");
this.adapterExecutor = checkNotNull(adapterExecutor, "adapterExecutor");
}
public void addListener(Runnable listener, Executor exec) {
executionList.add(listener, exec);
// When a listener is first added, we run a task that will wait for
// the future to finish, and when it is done will run the listeners.
if (!hasListeners.get() && hasListeners.compareAndSet(false, true)) {
executor.execute(new Runnable() {
/* @Override */
public void run() {
try {
future.get();
} catch (CancellationException e) {
// The task was cancelled, so it is done, run the listeners.
} catch (InterruptedException e) {
// This thread was interrupted. This should never happen, so we
// throw an IllegalStateException.
throw new IllegalStateException("Adapter thread interrupted!", e);
} catch (ExecutionException e) {
// The task caused an exception, so it is done, run the listeners.
}
executionList.run();
}
});
// the delegate to finish, and when it is done will run the listeners.
if (hasListeners.compareAndSet(false, true)) {
if (delegate.isDone()) {
// If the delegate is already done, run the execution list
// immediately on the current thread.
executionList.run();
return;
}
adapterExecutor.execute(new CallGetAndRunExecutionList<T>(delegate, executionList));
}
executionList.add(listener, exec);
}
Future<T> getFuture() {
return future;
return delegate;
}
ExecutorService getExecutor() {
return executor;
return adapterExecutor;
}
}
@ -119,27 +155,27 @@ public class Futures {
}
public static class LazyListenableFutureFunctionAdapter<I, O> extends ForwardingObject implements
ListenableFuture<O> {
ListenableFuture<O> {
private final FutureListener<I> futureListener;
private final Function<? super I, ? extends O> function;
static <I, O> LazyListenableFutureFunctionAdapter<I, O> create(Future<I> future,
Function<? super I, ? extends O> function, ExecutorService executor) {
Function<? super I, ? extends O> function, ExecutorService executor) {
return new LazyListenableFutureFunctionAdapter<I, O>(future, function, executor);
}
static <I, O> LazyListenableFutureFunctionAdapter<I, O> create(FutureListener<I> futureListener,
Function<? super I, ? extends O> function) {
Function<? super I, ? extends O> function) {
return new LazyListenableFutureFunctionAdapter<I, O>(futureListener, function);
}
private LazyListenableFutureFunctionAdapter(Future<I> future, Function<? super I, ? extends O> function,
ExecutorService executor) {
ExecutorService executor) {
this(FutureListener.create(future, executor), function);
}
private LazyListenableFutureFunctionAdapter(FutureListener<I> futureListener,
Function<? super I, ? extends O> function) {
Function<? super I, ? extends O> function) {
this.futureListener = checkNotNull(futureListener, "futureListener");
this.function = checkNotNull(function, "function");
}
@ -219,18 +255,19 @@ public class Futures {
* chaining, so that we don't invoke get() early.
*/
public static <I, O> ListenableFuture<O> compose(Future<I> future, final Function<? super I, ? extends O> function,
ExecutorService executorService) {
ExecutorService executorService) {
if (future instanceof Futures.ListenableFutureAdapter<?>) {
Futures.ListenableFutureAdapter<I> lf = (ListenableFutureAdapter<I>) future;
if (lf.futureListener.executor.getClass().isAnnotationPresent(SingleThreaded.class))
if (lf.futureListener.adapterExecutor.getClass().isAnnotationPresent(SingleThreaded.class))
return Futures.LazyListenableFutureFunctionAdapter.create(
((org.jclouds.concurrent.Futures.ListenableFutureAdapter<I>) future).futureListener, function);
((org.jclouds.concurrent.Futures.ListenableFutureAdapter<I>) future).futureListener, function);
else
return com.google.common.util.concurrent.Futures.compose(lf, function, executorService);
} else if (executorService.getClass().isAnnotationPresent(SingleThreaded.class)) {
return Futures.LazyListenableFutureFunctionAdapter.create(future, function, executorService);
} else {
return com.google.common.util.concurrent.Futures.compose(Futures.makeListenable(future, executorService), function, executorService);
return com.google.common.util.concurrent.Futures.compose(Futures.makeListenable(future, executorService),
function, executorService);
}
}

View File

@ -31,7 +31,7 @@ import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
@ -81,7 +81,7 @@ public class LocationModule extends AbstractModule {
@Memoized
protected Supplier<Set<? extends Location>> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final Supplier<Set<? extends Location>> locationSupplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException, seconds,
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException, seconds,
new Supplier<Set<? extends Location>>() {
@Override
public Set<? extends Location> get() {

View File

@ -19,6 +19,8 @@
package org.jclouds.rest.suppliers;
import static com.google.common.base.Suppliers.memoizeWithExpiration;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@ -26,8 +28,6 @@ import org.jclouds.concurrent.RetryOnTimeOutExceptionSupplier;
import org.jclouds.rest.AuthorizationException;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.base.Throwables;
/**
* This will retry the supplier if it encounters a timeout exception, but not if it encounters an
@ -44,33 +44,15 @@ import com.google.common.base.Throwables;
*
* @author Adrian Cole
*/
public class RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T> implements Supplier<T> {
public class MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T> implements Supplier<T> {
private final Supplier<T> delegate;
private final long seconds;
public RetryOnTimeOutButNotOnAuthorizationExceptionSupplier(
final AtomicReference<AuthorizationException> authException, final long seconds, final Supplier<T> delegate) {
this.delegate = Suppliers.<T> memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<T>(new Supplier<T>() {
public T get() {
if (authException.get() != null)
throw authException.get();
try {
return delegate.get();
} catch (AuthorizationException e) {
authException.set(e);
throw e;
} catch (Exception e) {
Throwables.propagate(e);
assert false : e;
return null;
}
}
@Override
public String toString() {
return "memoizeWithExpiration(" + delegate + ", seconds=" + seconds + ")";
}
}), seconds, TimeUnit.SECONDS);
public MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(
AtomicReference<AuthorizationException> authException, long seconds, Supplier<T> delegate) {
this.delegate = memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<T>(
new SetAndThrowAuthorizationExceptionSupplier<T>(delegate, authException)), seconds, TimeUnit.SECONDS);
this.seconds = seconds;
}
@Override
@ -80,7 +62,6 @@ public class RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T> implements
@Override
public String toString() {
return "RetryOnTimeOutButNotOnAuthorizationExceptionSupplier(" + delegate + ")";
return "memoizeWithExpiration(" + delegate + ", seconds=" + seconds + ")";
}
}

View File

@ -0,0 +1,71 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.rest.suppliers;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Throwables.propagate;
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;
import java.util.concurrent.atomic.AtomicReference;
import org.jclouds.rest.AuthorizationException;
import com.google.common.base.Supplier;
/**
*
* @author Adrian Cole
*/
public class SetAndThrowAuthorizationExceptionSupplier<T> implements Supplier<T> {
private final Supplier<T> delegate;
private final AtomicReference<AuthorizationException> authException;
public SetAndThrowAuthorizationExceptionSupplier(Supplier<T> delegate,
AtomicReference<AuthorizationException> authException) {
this.delegate = checkNotNull(delegate, "delegate");
this.authException = checkNotNull(authException, "authException");
}
public T get() {
if (authException.get() != null)
throw authException.get();
try {
return delegate.get();
} catch (AuthorizationException e) {
authException.set(e);
throw e;
} catch (Exception e) {
AuthorizationException aex = getFirstThrowableOfType(e, AuthorizationException.class);
if (aex != null) {
authException.set(aex);
throw aex;
}
propagate(e);
assert false : e;
return null;
}
}
@Override
public String toString() {
return "RetryOnTimeOutButNotOnAuthorizationExceptionSupplier(" + delegate + ")";
}
}

View File

@ -21,6 +21,9 @@ package org.jclouds.util;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Singleton;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.google.common.net.InetAddresses;
@ -31,26 +34,40 @@ import com.google.common.net.InetAddresses;
* @author Adrian Cole
*/
public class InetAddresses2 {
@Singleton
public static enum IsPrivateIPAddress implements Predicate<String> {
INSTANCE;
public boolean apply(String in) {
if (InetAddresses.isInetAddress(checkNotNull(in, "input address"))) {
// 24-bit Block (/8 prefix, 1/A) 10.0.0.0 10.255.255.255 16777216
if (in.indexOf("10.") == 0)
return true;
// 20-bit Block (/12 prefix, 16/B) 172.16.0.0 172.31.255.255 1048576
if (in.indexOf("172.") == 0) {
int second = Integer.parseInt(Iterables.get(Splitter.on('.').split(in), 1));
if (second >= 16 && second <= 31)
return true;
}
// 16-bit Block (/16 prefix, 256/C) 192.168.0.0 192.168.255.255 65536
if (in.indexOf("192.168.") == 0)
return true;
}
return false;
}
@Override
public String toString() {
return "isPrivateIPAddress()";
}
}
/**
* @return true if the input is an ip4 address and in one of the 3 reserved private blocks.
*/
public static boolean isPrivateIPAddress(String in) {
if (InetAddresses.isInetAddress(checkNotNull(in, "input address"))) {
// 24-bit Block (/8 prefix, 1 × A) 10.0.0.0 10.255.255.255 16777216
if (in.indexOf("10.") == 0)
return true;
// 20-bit Block (/12 prefix, 16 × B) 172.16.0.0 172.31.255.255 1048576
if (in.indexOf("172.") == 0) {
int second = Integer.parseInt(Iterables.get(Splitter.on('.').split(in), 1));
if (second >= 16 && second <= 31)
return true;
}
// 16-bit Block (/16 prefix, 256 × C) 192.168.0.0 192.168.255.255 65536
if (in.indexOf("192.168.") == 0)
return true;
}
return false;
return IsPrivateIPAddress.INSTANCE.apply(in);
}
}

View File

@ -67,7 +67,6 @@ public class Utils {
* @see Lists2#multiMax
*/
@Deprecated
@SuppressWarnings("unchecked")
public static <T, E extends T> List<E> multiMax(Comparator<T> ordering, Iterable<E> iterable) {
return Lists2.<T, E> multiMax(ordering, iterable);
}
@ -86,7 +85,6 @@ public class Utils {
* @see Throwables2#getFirstThrowableOfType(Throwable, Class)
*/
@Deprecated
@SuppressWarnings("unchecked")
public static <T extends Throwable> T getFirstThrowableOfType(Throwable from, Class<T> clazz) {
return Throwables2.<T> getFirstThrowableOfType(from, clazz);
}
@ -253,7 +251,6 @@ public class Utils {
* @see Providers#resolveContextBuilderClass
*/
@Deprecated
@SuppressWarnings("unchecked")
public static <S, A> Class<RestContextBuilder<S, A>> resolveContextBuilderClass(String provider,
Properties properties) throws ClassNotFoundException, IllegalArgumentException, SecurityException,
InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
@ -277,7 +274,6 @@ public class Utils {
* @see Providers#resolvePropertiesBuilderClass
*/
@Deprecated
@SuppressWarnings("unchecked")
public static Class<PropertiesBuilder> resolvePropertiesBuilderClass(String providerName, Properties props)
throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException,
NoSuchMethodException {

View File

@ -0,0 +1,93 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.concurrent;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import static org.testng.Assert.assertEquals;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import org.jclouds.concurrent.Futures.CallGetAndRunExecutionList;
import org.testng.annotations.Test;
import com.google.common.util.concurrent.ExecutionList;
/**
* Tests behavior of Futures
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class FuturesTest {
ExecutorService executorService = MoreExecutors.sameThreadExecutor();
@Test
public void testCallGetAndRunRunnableRunsListOnRuntimeException() throws InterruptedException, ExecutionException {
Runnable runnable = createMock(Runnable.class);
@SuppressWarnings("unchecked")
Future<String> future = createMock(Future.class);
runnable.run();
expect(future.get()).andThrow(new RuntimeException());
replay(runnable);
replay(future);
ExecutionList executionList = new ExecutionList();
executionList.add(runnable, executorService);
CallGetAndRunExecutionList<String> caller = new CallGetAndRunExecutionList<String>(future, executionList);
caller.run();
verify(runnable);
verify(future);
}
@Test
public void testCallGetAndRunRunnableInterruptsAndThrowsIllegalStateExceptionOnInterruptedException()
throws InterruptedException, ExecutionException {
Runnable runnable = createMock(Runnable.class);
@SuppressWarnings("unchecked")
Future<String> future = createMock(Future.class);
expect(future.get()).andThrow(new InterruptedException());
replay(runnable);
replay(future);
ExecutionList executionList = new ExecutionList();
executionList.add(runnable, executorService);
CallGetAndRunExecutionList<String> caller = new CallGetAndRunExecutionList<String>(future, executionList);
try {
caller.run();
assert false;
} catch (IllegalStateException e) {
assertEquals(e.getMessage(), "interrupted calling get() on [EasyMock for interface java.util.concurrent.Future], so could not run listeners");
}
verify(runnable);
verify(future);
}
}

View File

@ -0,0 +1,97 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.rest.suppliers;
import static org.testng.Assert.assertEquals;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
import org.jclouds.rest.AuthorizationException;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
/**
* Tests behavior of {@code SetAndThrowAuthorizationExceptionSupplier}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class SetAndThrowAuthorizationExceptionSupplierTest {
@Test
public void testNormal() {
AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
assertEquals(
new SetAndThrowAuthorizationExceptionSupplier<String>(Suppliers.ofInstance("foo"), authException).get(),
"foo");
assertEquals(authException.get(), null);
}
@Test(expectedExceptions = AuthorizationException.class)
public void testThrowsAuthorizationExceptionAndAlsoSetsExceptionType() {
AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
try {
new SetAndThrowAuthorizationExceptionSupplier<String>(new Supplier<String>() {
@Override
public String get() {
throw new AuthorizationException();
}
}, authException).get();
} finally {
assertEquals(authException.get().getClass(), AuthorizationException.class);
}
}
@Test(expectedExceptions = AuthorizationException.class)
public void testThrowsAuthorizationExceptionAndAlsoSetsExceptionTypeWhenNested() {
AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
try {
new SetAndThrowAuthorizationExceptionSupplier<String>(new Supplier<String>() {
@Override
public String get() {
throw new RuntimeException(new ExecutionException(new AuthorizationException()));
}
}, authException).get();
} finally {
assertEquals(authException.get().getClass(), AuthorizationException.class);
}
}
@Test(expectedExceptions = RuntimeException.class)
public void testThrowsOriginalExceptionAndAlsoSetsExceptionTypeWhenNestedAndNotAuthorizationException() {
AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
try {
new SetAndThrowAuthorizationExceptionSupplier<String>(new Supplier<String>() {
@Override
public String get() {
throw new RuntimeException(new IllegalArgumentException("foo"));
}
}, authException).get();
} finally {
assertEquals(authException.get().getClass(), RuntimeException.class);
}
}
}

View File

@ -31,7 +31,7 @@ import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
@ -79,7 +79,7 @@ public abstract class BaseLoadBalancerServiceContextModule extends AbstractModul
@Memoized
protected Supplier<Set<? extends Location>> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final Supplier<Set<? extends Location>> locationSupplier) {
return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException, seconds,
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException, seconds,
new Supplier<Set<? extends Location>>() {
@Override
public Set<? extends Location> get() {

View File

@ -36,7 +36,7 @@
<properties>
<test.aws-ec2.endpoint>https://ec2.us-east-1.amazonaws.com</test.aws-ec2.endpoint>
<test.aws-ec2.apiversion>2010-06-15</test.aws-ec2.apiversion>
<test.aws-ec2.apiversion>2010-11-15</test.aws-ec2.apiversion>
<test.aws-ec2.identity>${test.aws.identity}</test.aws-ec2.identity>
<test.aws-ec2.credential>${test.aws.credential}</test.aws-ec2.credential>
</properties>

View File

@ -21,6 +21,7 @@ package org.jclouds.aws.ec2;
import org.jclouds.aws.ec2.services.AWSAMIAsyncClient;
import org.jclouds.aws.ec2.services.AWSInstanceAsyncClient;
import org.jclouds.aws.ec2.services.AWSKeyPairAsyncClient;
import org.jclouds.aws.ec2.services.MonitoringAsyncClient;
import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient;
import org.jclouds.ec2.EC2AsyncClient;
@ -32,7 +33,7 @@ import org.jclouds.rest.annotations.Delegate;
* @author Adrian Cole
*/
public interface AWSEC2AsyncClient extends EC2AsyncClient {
public final static String VERSION = "2010-06-15";
public final static String VERSION = "2010-11-15";
/**
* {@inheritDoc}
@ -60,4 +61,10 @@ public interface AWSEC2AsyncClient extends EC2AsyncClient {
@Delegate
MonitoringAsyncClient getMonitoringServices();
/**
* {@inheritDoc}
*/
@Delegate
@Override
AWSKeyPairAsyncClient getKeyPairServices();
}

View File

@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.aws.ec2.services.AWSAMIClient;
import org.jclouds.aws.ec2.services.AWSInstanceClient;
import org.jclouds.aws.ec2.services.AWSKeyPairClient;
import org.jclouds.aws.ec2.services.MonitoringClient;
import org.jclouds.aws.ec2.services.PlacementGroupClient;
import org.jclouds.concurrent.Timeout;
@ -63,4 +64,10 @@ public interface AWSEC2Client extends EC2Client {
@Delegate
MonitoringClient getMonitoringServices();
/**
* {@inheritDoc}
*/
@Delegate
@Override
AWSKeyPairClient getKeyPairServices();
}

View File

@ -45,9 +45,9 @@ public class AWSEC2TemplateBuilderImpl extends EC2TemplateBuilderImpl {
@Inject
protected AWSEC2TemplateBuilderImpl(@Memoized Supplier<Set<? extends Location>> locations,
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
Supplier<Location> defaultLocation, Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider, Map<RegionAndName, Image> imageMap) {
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
Supplier<Location> defaultLocation, @Named("DEFAULT") Provider<TemplateOptions> optionsProvider,
@Named("DEFAULT") Provider<TemplateBuilder> defaultTemplateProvider, Map<RegionAndName, Image> imageMap) {
super(locations, images, sizes, defaultLocation, optionsProvider, defaultTemplateProvider, imageMap);
}

View File

@ -31,6 +31,8 @@ import org.jclouds.aws.ec2.services.AWSAMIAsyncClient;
import org.jclouds.aws.ec2.services.AWSAMIClient;
import org.jclouds.aws.ec2.services.AWSInstanceAsyncClient;
import org.jclouds.aws.ec2.services.AWSInstanceClient;
import org.jclouds.aws.ec2.services.AWSKeyPairAsyncClient;
import org.jclouds.aws.ec2.services.AWSKeyPairClient;
import org.jclouds.aws.ec2.services.MonitoringAsyncClient;
import org.jclouds.aws.ec2.services.MonitoringClient;
import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient;
@ -50,8 +52,6 @@ import org.jclouds.ec2.services.ElasticIPAddressAsyncClient;
import org.jclouds.ec2.services.ElasticIPAddressClient;
import org.jclouds.ec2.services.InstanceAsyncClient;
import org.jclouds.ec2.services.InstanceClient;
import org.jclouds.ec2.services.KeyPairAsyncClient;
import org.jclouds.ec2.services.KeyPairClient;
import org.jclouds.ec2.services.SecurityGroupAsyncClient;
import org.jclouds.ec2.services.SecurityGroupClient;
import org.jclouds.ec2.services.WindowsAsyncClient;
@ -75,7 +75,7 @@ public class AWSEC2RestClientModule extends EC2RestClientModule<AWSEC2Client, AW
.put(AWSAMIClient.class, AWSAMIAsyncClient.class)//
.put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)//
.put(AWSInstanceClient.class, AWSInstanceAsyncClient.class)//
.put(KeyPairClient.class, KeyPairAsyncClient.class)//
.put(AWSKeyPairClient.class, AWSKeyPairAsyncClient.class)//
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
.put(PlacementGroupClient.class, PlacementGroupAsyncClient.class)//
.put(MonitoringClient.class, MonitoringAsyncClient.class)//

View File

@ -0,0 +1,73 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.ec2.functions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Singleton;
import org.jclouds.crypto.CryptoStreams;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
/**
* @see <a href=
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-ImportKeyPair.html"
* />
* @author Adrian Cole
*/
@Singleton
public class EncodedRSAPublicKeyToBase64 implements Function<Object, String> {
private static Predicate<Object> startsWith(String value) {
return new ToStringStartsWith(value);
}
private static final class ToStringStartsWith implements Predicate<Object> {
private final String value;
private ToStringStartsWith(String value) {
this.value = value;
}
@Override
public boolean apply(Object input) {
return input.toString().startsWith(value);
}
public String toString() {
return "toStringStartsWith(" + value + ")";
}
}
@SuppressWarnings("unchecked")
private static final Predicate<Object> ALLOWED_MARKERS = Predicates.or(startsWith("ssh-rsa"),
startsWith("-----BEGIN CERTIFICATE-----"), startsWith("---- BEGIN SSH2 PUBLIC KEY ----"));
@Override
public String apply(Object from) {
checkNotNull(from, "input");
checkArgument(ALLOWED_MARKERS.apply(from), "must be a ssh public key, conforming to %s ", ALLOWED_MARKERS);
return CryptoStreams.base64(from.toString().getBytes(Charsets.UTF_8));
}
}

View File

@ -0,0 +1,66 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.ec2.services;
import static org.jclouds.aws.reference.FormParameters.ACTION;
import static org.jclouds.aws.reference.FormParameters.VERSION;
import javax.annotation.Nullable;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
import org.jclouds.aws.ec2.functions.EncodedRSAPublicKeyToBase64;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.services.KeyPairAsyncClient;
import org.jclouds.ec2.services.KeyPairClient;
import org.jclouds.ec2.xml.KeyPairResponseHandler;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
/**
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@FormParams(keys = VERSION, values = AWSEC2AsyncClient.VERSION)
@VirtualHost
public interface AWSKeyPairAsyncClient extends KeyPairAsyncClient {
/**
* @see KeyPairClient#importKeyPairInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "ImportKeyPair")
@XMLResponseParser(KeyPairResponseHandler.class)
ListenableFuture<KeyPair> importKeyPairInRegion(
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region,
@FormParam("KeyName") String keyName,
@FormParam("PublicKeyMaterial") @ParamParser(EncodedRSAPublicKeyToBase64.class) String publicKeyMaterial);
}

View File

@ -0,0 +1,71 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.ec2.services;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.concurrent.Timeout;
import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.ec2.services.KeyPairClient;
/**
*
* @author Adrian Cole
*/
@Timeout(duration = 90, timeUnit = TimeUnit.SECONDS)
public interface AWSKeyPairClient extends KeyPairClient {
/**
* Imports the public key from an RSA key pair that you created with a third-party tool. Compare
* this with CreateKeyPair, in which AWS creates the key pair and gives the keys to you (AWS
* keeps a copy of the public key). With ImportKeyPair, you create the key pair and give AWS just
* the public key. The private key is never transferred between you and AWS.
*
* <p/>
* You can easily create an RSA key pair on Windows and Linux using the ssh-keygen command line
* tool (provided with the standard OpenSSH installation). Standard library support for RSA key
* pair creation is also available in Java, Ruby, Python, and many other programming languages.
*
* <p/>
* <h4>Supported Formats</h4>
* <ul>
* <li>OpenSSH public key format (e.g., the format in ~/.ssh/authorized_keys)</li>
* <li>Base64 encoded DER format</li>
* <li>SSH public key file format as specified in RFC4716</li>
* </ul>
* DSA keys are not supported. Make sure your key generator is set up to create RSA keys.
* <p/>
* Supported lengths: 1024, 2048, and 4096.
* <p/>
*
* @param region
* region to import the key into
* @param keyName
* A unique name for the key pair. Accepts alphanumeric characters, spaces, dashes, and
* underscores.
* @param publicKeyMaterial
* The public key
* @return imported key including fingerprint
*/
KeyPair importKeyPairInRegion(@Nullable String region, String keyName, String publicKeyMaterial);
}

View File

@ -29,10 +29,10 @@ import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
import org.jclouds.aws.ec2.domain.MonitoringState;
import org.jclouds.aws.ec2.xml.MonitoringStateHandler;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.BinderParam;
@ -51,7 +51,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@FormParams(keys = VERSION, values = EC2AsyncClient.VERSION)
@FormParams(keys = VERSION, values = AWSEC2AsyncClient.VERSION)
@VirtualHost
public interface MonitoringAsyncClient {

View File

@ -29,10 +29,10 @@ import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
import org.jclouds.aws.ec2.domain.PlacementGroup;
import org.jclouds.aws.ec2.xml.DescribePlacementGroupsResponseHandler;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.binders.BindGroupNamesToIndexedFormParams;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.rest.annotations.BinderParam;
@ -54,7 +54,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@FormParams(keys = VERSION, values = EC2AsyncClient.VERSION)
@FormParams(keys = VERSION, values = AWSEC2AsyncClient.VERSION)
@VirtualHost
public interface PlacementGroupAsyncClient {

View File

@ -0,0 +1,28 @@
package org.jclouds.aws.ec2.functions;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code EncodedRSAPublicKeyToBase64}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class EncodedRSAPublicKeyToBase64Test {
EncodedRSAPublicKeyToBase64 function = new EncodedRSAPublicKeyToBase64();
public void testAllowedMarkers() throws IOException {
assertEquals(function.apply("-----BEGIN CERTIFICATE-----"), "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t");
assertEquals(function.apply("ssh-rsa"), "c3NoLXJzYQ==");
assertEquals(function.apply("---- BEGIN SSH2 PUBLIC KEY ----"), "LS0tLSBCRUdJTiBTU0gyIFBVQkxJQyBLRVkgLS0tLQ==");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testDisallowedMarkersIllegalArgument() throws IOException {
function.apply("ssh-dsa");
}
}

View File

@ -58,13 +58,13 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testCreateImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("createImageInRegion", String.class, String.class,
String.class, Array.newInstance(CreateImageOptions.class, 0).getClass());
String.class, Array.newInstance(CreateImageOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "name", "instanceId");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=CreateImage&InstanceId=instanceId&Name=name",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=CreateImage&InstanceId=instanceId&Name=name",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
assertExceptionParserClassEquals(method, null);
@ -74,16 +74,16 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testCreateImageOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("createImageInRegion", String.class, String.class,
String.class, Array.newInstance(CreateImageOptions.class, 0).getClass());
String.class, Array.newInstance(CreateImageOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "name", "instanceId", new CreateImageOptions()
.withDescription("description").noReboot());
.withDescription("description").noReboot());
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=CreateImage&InstanceId=instanceId&Name=name&Description=description&NoReboot=true",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=CreateImage&InstanceId=instanceId&Name=name&Description=description&NoReboot=true",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
@ -93,19 +93,19 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
}
public void testDescribeImages() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("describeImagesInRegion", String.class, Array.newInstance(
DescribeImagesOptions.class, 0).getClass());
Method method = AWSAMIAsyncClient.class.getMethod("describeImagesInRegion", String.class,
Array.newInstance(DescribeImagesOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, (String) null);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeImages", "application/x-www-form-urlencoded",
false);
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeImages", "application/x-www-form-urlencoded",
false);
filter.filter(request);
assertPayloadEquals(
request,
"Action=DescribeImages&Signature=qE4vexSFJqS0UWK%2BccV3s%2BP9woL3M5HI5bTBoM7s%2FLY%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2010-06-15&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded", false);
request,
"Action=DescribeImages&Signature=1gIaOJ%2F0Wc8ZFl8GeinQzYAfD%2FOQCKLH32VLcOippGY%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2010-11-15&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class);
@ -115,17 +115,17 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
}
public void testDescribeImagesOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("describeImagesInRegion", String.class, Array.newInstance(
DescribeImagesOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, executableBy("me").ownedBy("fred", "nancy").imageIds(
"1", "2"));
Method method = AWSAMIAsyncClient.class.getMethod("describeImagesInRegion", String.class,
Array.newInstance(DescribeImagesOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null,
executableBy("me").ownedBy("fred", "nancy").imageIds("1", "2"));
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=DescribeImages&ExecutableBy=me&Owner.1=fred&Owner.2=nancy&ImageId.1=1&ImageId.2=2",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=DescribeImages&ExecutableBy=me&Owner.1=fred&Owner.2=nancy&ImageId.1=1&ImageId.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class);
@ -140,8 +140,8 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DeregisterImage&ImageId=imageId",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=DeregisterImage&ImageId=imageId",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -152,13 +152,13 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testRegisterImageFromManifest() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("registerImageFromManifestInRegion", String.class,
String.class, String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass());
String.class, String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "name", "pathToManifest");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=RegisterImage&ImageLocation=pathToManifest&Name=name",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=RegisterImage&ImageLocation=pathToManifest&Name=name",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
assertExceptionParserClassEquals(method, null);
@ -168,16 +168,15 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testRegisterImageFromManifestOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("registerImageFromManifestInRegion", String.class,
String.class, String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "name", "pathToManifest", new RegisterImageOptions()
.withDescription("description"));
String.class, String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "name", "pathToManifest",
new RegisterImageOptions().withDescription("description"));
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=RegisterImage&ImageLocation=pathToManifest&Name=name&Description=description",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request,
"Version=2010-11-15&Action=RegisterImage&ImageLocation=pathToManifest&Name=name&Description=description",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
@ -188,15 +187,15 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testRegisterImageBackedByEBS() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("registerUnixImageBackedByEbsInRegion", String.class,
String.class, String.class, Array.newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass());
String.class, String.class, Array.newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "imageName", "snapshotId");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
assertExceptionParserClassEquals(method, null);
@ -206,17 +205,22 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testRegisterImageBackedByEBSOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("registerUnixImageBackedByEbsInRegion", String.class,
String.class, String.class, Array.newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "imageName", "snapshotId",
new RegisterImageBackedByEbsOptions().withDescription("description").addBlockDeviceFromSnapshot(
"/dev/device", null, "snapshot").addNewBlockDevice("/dev/newdevice", "newblock", 100));
String.class, String.class, Array.newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(
method,
null,
"imageName",
"snapshotId",
new RegisterImageBackedByEbsOptions().withDescription("description")
.addBlockDeviceFromSnapshot("/dev/device", null, "snapshot")
.addNewBlockDevice("/dev/newdevice", "newblock", 100));
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName&Description=description&BlockDeviceMapping.1.Ebs.DeleteOnTermination=false&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fdevice&BlockDeviceMapping.1.Ebs.SnapshotId=snapshot&BlockDeviceMapping.2.Ebs.DeleteOnTermination=false&BlockDeviceMapping.2.DeviceName=%2Fdev%2Fnewdevice&BlockDeviceMapping.2.VirtualName=newblock&BlockDeviceMapping.2.Ebs.VolumeSize=100",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName&Description=description&BlockDeviceMapping.1.Ebs.DeleteOnTermination=false&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fdevice&BlockDeviceMapping.1.Ebs.SnapshotId=snapshot&BlockDeviceMapping.2.Ebs.DeleteOnTermination=false&BlockDeviceMapping.2.DeviceName=%2Fdev%2Fnewdevice&BlockDeviceMapping.2.VirtualName=newblock&BlockDeviceMapping.2.Ebs.VolumeSize=100",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, ImageIdHandler.class);
@ -232,8 +236,8 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=DescribeImageAttribute&Attribute=productCodes&ImageId=imageId",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=DescribeImageAttribute&Attribute=productCodes&ImageId=imageId",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, ProductCodesHandler.class);
@ -244,14 +248,14 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testGetBlockDeviceMappingsForImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("getBlockDeviceMappingsForImageInRegion", String.class,
String.class);
String.class);
HttpRequest request = processor.createRequest(method, null, "imageId");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=DescribeImageAttribute&Attribute=blockDeviceMapping&ImageId=imageId",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=DescribeImageAttribute&Attribute=blockDeviceMapping&ImageId=imageId",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, BlockDeviceMappingHandler.class);
@ -262,14 +266,14 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testGetLaunchPermissionForImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("getLaunchPermissionForImageInRegion", String.class,
String.class);
String.class);
HttpRequest request = processor.createRequest(method, null, "imageId");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=DescribeImageAttribute&Attribute=launchPermission&ImageId=imageId",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=DescribeImageAttribute&Attribute=launchPermission&ImageId=imageId",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, PermissionHandler.class);
@ -280,21 +284,21 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testAddLaunchPermissionsToImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("addLaunchPermissionsToImageInRegion", String.class,
Iterable.class, Iterable.class, String.class);
HttpRequest request = processor.createRequest(method, null, ImmutableList.of("bob", "sue"), ImmutableList
.of("all"), "imageId");
Iterable.class, Iterable.class, String.class);
HttpRequest request = processor.createRequest(method, null, ImmutableList.of("bob", "sue"),
ImmutableList.of("all"), "imageId");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=ModifyImageAttribute&OperationType=add&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=ModifyImageAttribute&OperationType=add&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue",
"application/x-www-form-urlencoded", false);
filter.filter(request);
assertPayloadEquals(
request,
"Action=ModifyImageAttribute&Attribute=launchPermission&ImageId=imageId&OperationType=add&Signature=WZzNWOC1KHbuySvXEuLTiBA%2BVUfKpSBN2Lud6MrhlCQ%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&UserGroup.1=all&UserId.1=bob&UserId.2=sue&Version=2010-06-15&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded", false);
request,
"Action=ModifyImageAttribute&Attribute=launchPermission&ImageId=imageId&OperationType=add&Signature=UvMbUlLld2h7MpNmuc9JSuOjDw4DS6PSNQVlBdBc%2FBQ%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&UserGroup.1=all&UserId.1=bob&UserId.2=sue&Version=2010-11-15&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -305,16 +309,16 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testRemoveLaunchPermissionsFromImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("removeLaunchPermissionsFromImageInRegion", String.class,
Iterable.class, Iterable.class, String.class);
HttpRequest request = processor.createRequest(method, null, ImmutableList.of("bob", "sue"), ImmutableList
.of("all"), "imageId");
Iterable.class, Iterable.class, String.class);
HttpRequest request = processor.createRequest(method, null, ImmutableList.of("bob", "sue"),
ImmutableList.of("all"), "imageId");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -324,14 +328,14 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testResetLaunchPermissionsOnImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("resetLaunchPermissionsOnImageInRegion", String.class,
String.class);
String.class);
HttpRequest request = processor.createRequest(method, null, "imageId");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=ResetImageAttribute&Attribute=launchPermission&ImageId=imageId",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=ResetImageAttribute&Attribute=launchPermission&ImageId=imageId",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -341,15 +345,15 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testAddProductCodesToImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("addProductCodesToImageInRegion", String.class, Iterable.class,
String.class);
String.class);
HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=ModifyImageAttribute&OperationType=add&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=ModifyImageAttribute&OperationType=add&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -360,15 +364,15 @@ public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSAMIAsync
public void testRemoveProductCodesFromImage() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSAMIAsyncClient.class.getMethod("removeProductCodesFromImageInRegion", String.class,
Iterable.class, String.class);
Iterable.class, String.class);
HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);

View File

@ -62,8 +62,8 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeInstances", "application/x-www-form-urlencoded",
false);
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeInstances", "application/x-www-form-urlencoded",
false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, AWSDescribeInstancesResponseHandler.class);
@ -78,8 +78,8 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeInstances&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeInstances&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, AWSDescribeInstancesResponseHandler.class);
@ -90,13 +90,13 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testTerminateInstances() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("terminateInstancesInRegion", String.class, Array
.newInstance(String.class, 0).getClass());
.newInstance(String.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "1", "2");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=TerminateInstances&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=TerminateInstances&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InstanceStateChangeHandler.class);
@ -107,18 +107,18 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testRunInstances() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("runInstancesInRegion", String.class, String.class,
String.class, int.class, int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass());
String.class, int.class, int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, null, "ami-voo", 1, 1);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
try {
assertPayloadEquals(request, "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=1",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=1",
"application/x-www-form-urlencoded", false);
} catch (AssertionError e) {
// mvn 3.0 osx 10.6.5 somehow sorts differently
assertPayloadEquals(request, "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MaxCount=1&MinCount=1",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=RunInstances&ImageId=ami-voo&MaxCount=1&MinCount=1",
"application/x-www-form-urlencoded", false);
}
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, AWSRunInstancesResponseHandler.class);
@ -129,24 +129,30 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testRunInstancesOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("runInstancesInRegion", String.class, String.class,
String.class, int.class, int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, "us-east-1", "us-east-1a", "ami-voo",
1, 5, new AWSRunInstancesOptions().withKernelId("kernelId").enableMonitoring().withSecurityGroups(
"group1", "group2"));
String.class, int.class, int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(
method,
"us-east-1",
"us-east-1a",
"ami-voo",
1,
5,
new AWSRunInstancesOptions().withKernelId("kernelId").enableMonitoring()
.withSecurityGroups("group1", "group2"));
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
try {
assertPayloadEquals(
request,
"Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=5&KernelId=kernelId&Monitoring.Enabled=true&SecurityGroup.1=group1&SecurityGroup.2=group2&Placement.AvailabilityZone=us-east-1a",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=5&KernelId=kernelId&Monitoring.Enabled=true&SecurityGroup.1=group1&SecurityGroup.2=group2&Placement.AvailabilityZone=us-east-1a",
"application/x-www-form-urlencoded", false);
} catch (AssertionError e) {
// mvn 3.0 osx 10.6.5 somehow sorts differently
assertPayloadEquals(
request,
"Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MaxCount=5&MinCount=1&KernelId=kernelId&Monitoring.Enabled=true&SecurityGroup.1=group1&SecurityGroup.2=group2&Placement.AvailabilityZone=us-east-1a",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=RunInstances&ImageId=ami-voo&MaxCount=5&MinCount=1&KernelId=kernelId&Monitoring.Enabled=true&SecurityGroup.1=group1&SecurityGroup.2=group2&Placement.AvailabilityZone=us-east-1a",
"application/x-www-form-urlencoded", false);
}
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, AWSRunInstancesResponseHandler.class);
@ -157,13 +163,13 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testStopInstances() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("stopInstancesInRegion", String.class, boolean.class,
Array.newInstance(String.class, 0).getClass());
Array.newInstance(String.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, true, "1", "2");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=StopInstances&Force=true&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=StopInstances&Force=true&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InstanceStateChangeHandler.class);
@ -174,13 +180,13 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testRebootInstances() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("rebootInstancesInRegion", String.class, Array
.newInstance(String.class, 0).getClass());
.newInstance(String.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "1", "2");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=RebootInstances&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=RebootInstances&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -190,14 +196,14 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
}
public void testStartInstances() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("startInstancesInRegion", String.class, Array.newInstance(
String.class, 0).getClass());
Method method = AWSInstanceAsyncClient.class.getMethod("startInstancesInRegion", String.class,
Array.newInstance(String.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "1", "2");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=StartInstances&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=StartInstances&InstanceId.1=1&InstanceId.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InstanceStateChangeHandler.class);
@ -208,14 +214,14 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testGetUserDataForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("getUserDataForInstanceInRegion", String.class,
String.class);
String.class);
HttpRequest request = processor.createRequest(method, null, "1");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=userData&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=DescribeInstanceAttribute&Attribute=userData&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, UnencodeStringValueHandler.class);
@ -226,14 +232,14 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testGetRootDeviceNameForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("getRootDeviceNameForInstanceInRegion", String.class,
String.class);
String.class);
HttpRequest request = processor.createRequest(method, null, "1");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=rootDeviceName&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=DescribeInstanceAttribute&Attribute=rootDeviceName&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, StringValueHandler.class);
@ -244,14 +250,14 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testGetRamdiskForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("getRamdiskForInstanceInRegion", String.class,
String.class);
String.class);
HttpRequest request = processor.createRequest(method, null, "1");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=ramdisk&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=DescribeInstanceAttribute&Attribute=ramdisk&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, StringValueHandler.class);
@ -261,16 +267,16 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
}
public void testGetDisableApiTerminationForInstanceInRegion() throws SecurityException, NoSuchMethodException,
IOException {
IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("isApiTerminationDisabledForInstanceInRegion",
String.class, String.class);
String.class, String.class);
HttpRequest request = processor.createRequest(method, null, "1");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=disableApiTermination&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=DescribeInstanceAttribute&Attribute=disableApiTermination&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, BooleanValueHandler.class);
@ -281,13 +287,13 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testGetKernelForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class
.getMethod("getKernelForInstanceInRegion", String.class, String.class);
.getMethod("getKernelForInstanceInRegion", String.class, String.class);
HttpRequest request = processor.createRequest(method, null, "1");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=kernel&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeInstanceAttribute&Attribute=kernel&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, StringValueHandler.class);
@ -298,14 +304,14 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testGetInstanceTypeForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("getInstanceTypeForInstanceInRegion", String.class,
String.class);
String.class);
HttpRequest request = processor.createRequest(method, null, "1");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=instanceType&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=DescribeInstanceAttribute&Attribute=instanceType&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InstanceTypeHandler.class);
@ -315,17 +321,17 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
}
public void testGetInstanceInitiatedShutdownBehaviorForInstanceInRegion() throws SecurityException,
NoSuchMethodException, IOException {
NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("getInstanceInitiatedShutdownBehaviorForInstanceInRegion",
String.class, String.class);
String.class, String.class);
HttpRequest request = processor.createRequest(method, null, "1");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=instanceInitiatedShutdownBehavior&InstanceId=1",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=DescribeInstanceAttribute&Attribute=instanceInitiatedShutdownBehavior&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InstanceInitiatedShutdownBehaviorHandler.class);
@ -335,16 +341,16 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
}
public void testGetBlockDeviceMappingForInstanceInRegion() throws SecurityException, NoSuchMethodException,
IOException {
IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("getBlockDeviceMappingForInstanceInRegion", String.class,
String.class);
String.class);
HttpRequest request = processor.createRequest(method, null, "1");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=blockDeviceMapping&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=DescribeInstanceAttribute&Attribute=blockDeviceMapping&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, BlockDeviceMappingHandler.class);
@ -355,19 +361,19 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testSetUserDataForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("setUserDataForInstanceInRegion", String.class,
String.class, Array.newInstance(byte.class, 0).getClass());
String.class, Array.newInstance(byte.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "1", "test".getBytes());
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=userData&Value=dGVzdA%3D%3D&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=ModifyInstanceAttribute&Attribute=userData&Value=dGVzdA%3D%3D&InstanceId=1",
"application/x-www-form-urlencoded", false);
filter.filter(request);// ensure encoding worked properly
assertPayloadEquals(
request,
"Action=ModifyInstanceAttribute&Attribute=userData&InstanceId=1&Signature=LfUmzLM5DsACR5nQcEfGF5FPdznOwwhJ7tjhBWfHtGs%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Value=dGVzdA%3D%3D&Version=2010-06-15&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded", false);
request,
"Action=ModifyInstanceAttribute&Attribute=userData&InstanceId=1&Signature=B15Bj0yiAMTwpHE%2B9LNNscM4fzFwv0t0adnYbFjgNDk%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Value=dGVzdA%3D%3D&Version=2010-11-15&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -377,14 +383,14 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testSetRamdiskForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("setRamdiskForInstanceInRegion", String.class,
String.class, String.class);
String.class, String.class);
HttpRequest request = processor.createRequest(method, null, "1", "test");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=ramdisk&Value=test&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=ModifyInstanceAttribute&Attribute=ramdisk&Value=test&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -394,14 +400,14 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testSetKernelForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("setKernelForInstanceInRegion", String.class,
String.class, String.class);
String.class, String.class);
HttpRequest request = processor.createRequest(method, null, "1", "test");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=kernel&Value=test&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=ModifyInstanceAttribute&Attribute=kernel&Value=test&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@ -410,17 +416,17 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
}
public void testSetApiTerminationDisabledForInstanceInRegion() throws SecurityException, NoSuchMethodException,
IOException {
IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("setApiTerminationDisabledForInstanceInRegion",
String.class, String.class, boolean.class);
String.class, String.class, boolean.class);
HttpRequest request = processor.createRequest(method, null, "1", true);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=disableApiTermination&Value=true&InstanceId=1",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=ModifyInstanceAttribute&Attribute=disableApiTermination&Value=true&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -431,14 +437,14 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
public void testSetInstanceTypeForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("setInstanceTypeForInstanceInRegion", String.class,
String.class, String.class);
String.class, String.class);
HttpRequest request = processor.createRequest(method, null, "1", InstanceType.C1_MEDIUM);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=instanceType&Value=c1.medium&InstanceId=1",
"application/x-www-form-urlencoded", false);
"Version=2010-11-15&Action=ModifyInstanceAttribute&Attribute=instanceType&Value=c1.medium&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -448,17 +454,17 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
}
public void testSetInstanceInitiatedShutdownBehaviorForInstanceInRegion() throws SecurityException,
NoSuchMethodException, IOException {
NoSuchMethodException, IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("setInstanceInitiatedShutdownBehaviorForInstanceInRegion",
String.class, String.class, InstanceInitiatedShutdownBehavior.class);
String.class, String.class, InstanceInitiatedShutdownBehavior.class);
HttpRequest request = processor.createRequest(method, null, "1", InstanceInitiatedShutdownBehavior.TERMINATE);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=instanceInitiatedShutdownBehavior&Value=terminate&InstanceId=1",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=ModifyInstanceAttribute&Attribute=instanceInitiatedShutdownBehavior&Value=terminate&InstanceId=1",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
@ -468,9 +474,9 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
}
public void testSetBlockDeviceMappingForInstanceInRegion() throws SecurityException, NoSuchMethodException,
IOException {
IOException {
Method method = AWSInstanceAsyncClient.class.getMethod("setBlockDeviceMappingForInstanceInRegion", String.class,
String.class, Map.class);
String.class, Map.class);
Map<String, BlockDevice> mapping = Maps.newLinkedHashMap();
mapping.put("/dev/sda1", new BlockDevice("vol-test1", true));
@ -479,14 +485,14 @@ public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSIns
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(
request,
"Version=2010-06-15&Action=ModifyInstanceAttribute&InstanceId=1&BlockDeviceMapping.1.Ebs.VolumeId=vol-test1&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true",
"application/x-www-form-urlencoded", false);
request,
"Version=2010-11-15&Action=ModifyInstanceAttribute&InstanceId=1&BlockDeviceMapping.1.Ebs.VolumeId=vol-test1&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true",
"application/x-www-form-urlencoded", false);
filter.filter(request);// ensure encoding worked properly
assertPayloadEquals(
request,
"Action=ModifyInstanceAttribute&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true&BlockDeviceMapping.1.Ebs.VolumeId=vol-test1&InstanceId=1&Signature=RwY8lVPHSQxQkd5efUKccHdSTkN4OxMIMFiYAe3rrUE%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2010-06-15&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded", false);
request,
"Action=ModifyInstanceAttribute&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true&BlockDeviceMapping.1.Ebs.VolumeId=vol-test1&InstanceId=1&Signature=Cf8vx1IzPe%2FFYd7SRJBjztSOB3FQTW9yYtPxQ3OUHF0%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2010-11-15&AWSAccessKeyId=identity",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);

View File

@ -0,0 +1,135 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.ec2.services;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import org.jclouds.ec2.xml.DescribeKeyPairsResponseHandler;
import org.jclouds.ec2.xml.KeyPairResponseHandler;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code AWSKeyPairAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire
@Test(groups = "unit", testName = "AWSKeyPairAsyncClientTest")
public class AWSKeyPairAsyncClientTest extends BaseAWSEC2AsyncClientTest<AWSKeyPairAsyncClient> {
public void testCreateKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSKeyPairAsyncClient.class.getMethod("createKeyPairInRegion", String.class, String.class);
HttpRequest request = processor.createRequest(method, null, "mykey");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-11-15&Action=CreateKeyPair&KeyName=mykey",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, KeyPairResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testImportKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSKeyPairAsyncClient.class.getMethod("importKeyPairInRegion", String.class, String.class,
String.class);
HttpRequest request = processor.createRequest(method, null, "mykey", "ssh-rsa AA");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-11-15&Action=ImportKeyPair&PublicKeyMaterial=c3NoLXJzYSBBQQ%3D%3D&KeyName=mykey",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, KeyPairResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSKeyPairAsyncClient.class.getMethod("deleteKeyPairInRegion", String.class, String.class);
HttpRequest request = processor.createRequest(method, null, "mykey");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-11-15&Action=DeleteKeyPair&KeyName=mykey",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testDescribeKeyPairs() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSKeyPairAsyncClient.class.getMethod("describeKeyPairsInRegion", String.class, Array
.newInstance(String.class, 0).getClass());
HttpRequest request = processor.createRequest(method, (String) null);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeKeyPairs", "application/x-www-form-urlencoded",
false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeKeyPairsResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testDescribeKeyPairsArgs() throws SecurityException, NoSuchMethodException, IOException {
Method method = AWSKeyPairAsyncClient.class.getMethod("describeKeyPairsInRegion", String.class, Array
.newInstance(String.class, 0).getClass());
HttpRequest request = processor.createRequest(method, null, "1", "2");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribeKeyPairs&KeyName.1=1&KeyName.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeKeyPairsResponseHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<AWSKeyPairAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<AWSKeyPairAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,178 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.ec2.services;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.AWSEC2AsyncClient;
import org.jclouds.aws.ec2.AWSEC2Client;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.ComputeTestUtils;
import org.jclouds.ec2.domain.KeyPair;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Module;
/**
* Tests behavior of {@code AWSKeyPairClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true)
public class AWSKeyPairClientLiveTest {
private AWSKeyPairClient client;
private RestContext<AWSEC2Client, AWSEC2AsyncClient> context;
protected String provider = "aws-ec2";
protected String identity;
protected String credential;
protected String endpoint;
protected String apiversion;
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint", null);
apiversion = System.getProperty("test." + provider + ".apiversion", null);
}
protected Properties setupProperties() {
Properties overrides = new Properties();
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
overrides.setProperty(provider + ".identity", identity);
overrides.setProperty(provider + ".credential", credential);
if (endpoint != null)
overrides.setProperty(provider + ".endpoint", endpoint);
if (apiversion != null)
overrides.setProperty(provider + ".apiversion", apiversion);
return overrides;
}
@BeforeGroups(groups = { "live" })
public void setupClient() {
setupCredentials();
Properties overrides = setupProperties();
context = new ComputeServiceContextFactory().createContext(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
client = context.getApi().getKeyPairServices();
}
@Test
void testDescribeAWSKeyPairs() {
for (String region : Region.DEFAULT_REGIONS) {
SortedSet<KeyPair> allResults = Sets.newTreeSet(client.describeKeyPairsInRegion(region));
assertNotNull(allResults);
if (allResults.size() >= 1) {
KeyPair pair = allResults.last();
SortedSet<KeyPair> result = Sets.newTreeSet(client.describeKeyPairsInRegion(region, pair.getKeyName()));
assertNotNull(result);
KeyPair compare = result.last();
assertEquals(compare, pair);
}
}
}
public static final String PREFIX = System.getProperty("user.name") + "-ec2";
@Test
void testCreateKeyPair() {
String keyName = PREFIX + "1";
cleanupKeyPair(keyName);
try {
KeyPair keyPair = client.createKeyPairInRegion(null, keyName);
checkKeyPair(keyName, keyPair);
assertNotNull(keyPair.getKeyMaterial());
} finally {
cleanupKeyPair(keyName);
}
}
protected void cleanupKeyPair(String keyName) {
try {
client.deleteKeyPairInRegion(null, keyName);
} catch (Exception e) {
}
client.deleteKeyPairInRegion(null, keyName);
}
@Test
void testImportKeyPair() throws FileNotFoundException, IOException {
String keyName = PREFIX + "2";
cleanupKeyPair(keyName);
Map<String, String> myKey = ComputeTestUtils.setupKeyPair();
try {
KeyPair keyPair = client.importKeyPairInRegion(null, keyName, myKey.get("public"));
checkKeyPair(keyName, keyPair);
// TODO generate correct fingerprint and check
// assertEquals(keyPair.getKeyFingerprint(),
// CryptoStreams.hex(CryptoStreams.md5(myKey.get("public").getBytes())));
// try again to see if there's an error
try {
client.importKeyPairInRegion(null, keyName, myKey.get("public"));
assert false;
} catch (IllegalStateException e) {
}
} finally {
cleanupKeyPair(keyName);
}
}
protected void checkKeyPair(String keyName, KeyPair keyPair) {
assertNotNull(keyPair);
assertNotNull(keyPair.getKeyFingerprint());
assertEquals(keyPair.getKeyName(), keyName);
Set<KeyPair> twoResults = Sets.newLinkedHashSet(client.describeKeyPairsInRegion(null, keyName));
assertNotNull(twoResults);
assertEquals(twoResults.size(), 1);
KeyPair listPair = twoResults.iterator().next();
assertEquals(listPair.getKeyName(), keyPair.getKeyName());
assertEquals(listPair.getKeyFingerprint(), keyPair.getKeyFingerprint());
}
@AfterTest
public void shutdown() {
context.close();
}
}

View File

@ -46,7 +46,7 @@ public class MonitoringAsyncClientTest extends BaseAWSEC2AsyncClientTest<Monitor
HttpRequest request = processor.createRequest(method, null, "instance1", "instance2");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
String payload = "Version=2010-06-15&Action=UnmonitorInstances&InstanceId.0=instance1&InstanceId.1=instance2";
String payload = "Version=2010-11-15&Action=UnmonitorInstances&InstanceId.0=instance1&InstanceId.1=instance2";
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, payload, "application/x-www-form-urlencoded", false);
@ -65,7 +65,7 @@ public class MonitoringAsyncClientTest extends BaseAWSEC2AsyncClientTest<Monitor
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request,
"Version=2010-06-15&Action=MonitorInstances&InstanceId.0=instance1&InstanceId.1=instance2",
"Version=2010-11-15&Action=MonitorInstances&InstanceId.0=instance1&InstanceId.1=instance2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);

View File

@ -49,7 +49,7 @@ public class PlacementGroupAsyncClientTest extends BaseAWSEC2AsyncClientTest<Pla
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DeletePlacementGroup&GroupName=name",
assertPayloadEquals(request, "Version=2010-11-15&Action=DeletePlacementGroup&GroupName=name",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
@ -66,7 +66,7 @@ public class PlacementGroupAsyncClientTest extends BaseAWSEC2AsyncClientTest<Pla
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=CreatePlacementGroup&Strategy=cluster&GroupName=name",
assertPayloadEquals(request, "Version=2010-11-15&Action=CreatePlacementGroup&Strategy=cluster&GroupName=name",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
@ -83,7 +83,7 @@ public class PlacementGroupAsyncClientTest extends BaseAWSEC2AsyncClientTest<Pla
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=CreatePlacementGroup&Strategy=cluster&GroupName=name",
assertPayloadEquals(request, "Version=2010-11-15&Action=CreatePlacementGroup&Strategy=cluster&GroupName=name",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
@ -100,7 +100,7 @@ public class PlacementGroupAsyncClientTest extends BaseAWSEC2AsyncClientTest<Pla
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DescribePlacementGroups",
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribePlacementGroups",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -117,7 +117,7 @@ public class PlacementGroupAsyncClientTest extends BaseAWSEC2AsyncClientTest<Pla
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DescribePlacementGroups&GroupName.1=1&GroupName.2=2",
assertPayloadEquals(request, "Version=2010-11-15&Action=DescribePlacementGroups&GroupName.1=1&GroupName.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);

View File

@ -34,4 +34,8 @@ public class BlueLockVCloudDirectorGuestCustomizationLiveTest extends VCloudGues
provider = "bluelock-vcdirector";
}
@Override
protected void checkApiOutput(String apiOutput) {
checkApiOutput1_0_0(apiOutput);
}
}

View File

@ -456,7 +456,7 @@ public class IBMDeveloperCloudAsyncClientTest extends RestClientTest<IBMDevelope
assertRequestLineEquals(httpRequest,
"POST https://www-147.ibm.com/computecloud/enterprise/api/rest/20100331/storage HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
assertPayloadEquals(httpRequest, "location=location&format=format&name=name&offeringID=offering&size=size",
assertPayloadEquals(httpRequest, "location=location&format=format&name=name&size=size&offeringID=offering",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, httpRequest, ParseVolumeFromJson.class);

View File

@ -23,26 +23,53 @@ import java.net.URI;
import javax.annotation.Nullable;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.jclouds.predicates.validators.DnsNameValidator;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.ParamValidators;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.savvis.vpdc.domain.SymphonyVPDCVDC;
import org.jclouds.savvis.vpdc.xml.SymphonyVPDCNetworkHandler;
import org.jclouds.savvis.vpdc.xml.SymphonyVPDCVAppHandler;
import org.jclouds.savvis.vpdc.xml.SymphonyVPDCVDCHandler;
import org.jclouds.vcloud.CommonVCloudClient;
import org.jclouds.vcloud.VCloudExpressAsyncClient;
import org.jclouds.vcloud.VCloudExpressClient;
import org.jclouds.vcloud.binders.BindCloneVAppParamsToXmlPayload;
import org.jclouds.vcloud.binders.BindInstantiateVCloudExpressVAppTemplateParamsToXmlPayload;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.Org;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.TasksList;
import org.jclouds.vcloud.domain.VCloudExpressVApp;
import org.jclouds.vcloud.domain.VDC;
import org.jclouds.vcloud.domain.VCloudExpressVAppTemplate;
import org.jclouds.vcloud.domain.network.OrgNetwork;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.functions.OrgNameAndCatalogNameToEndpoint;
import org.jclouds.vcloud.functions.OrgNameAndVDCNameToEndpoint;
import org.jclouds.vcloud.functions.OrgNameCatalogNameItemNameToEndpoint;
import org.jclouds.vcloud.functions.OrgNameCatalogNameVAppTemplateNameToEndpoint;
import org.jclouds.vcloud.functions.OrgNameToEndpoint;
import org.jclouds.vcloud.functions.OrgNameToTasksListEndpoint;
import org.jclouds.vcloud.functions.OrgNameVDCNameResourceEntityNameToEndpoint;
import org.jclouds.vcloud.options.CloneVAppOptions;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import org.jclouds.vcloud.xml.CatalogHandler;
import org.jclouds.vcloud.xml.CatalogItemHandler;
import org.jclouds.vcloud.xml.OrgHandler;
import org.jclouds.vcloud.xml.VDCHandler;
import org.jclouds.vcloud.xml.TaskHandler;
import org.jclouds.vcloud.xml.TasksListHandler;
import org.jclouds.vcloud.xml.VCloudExpressVAppHandler;
import org.jclouds.vcloud.xml.VCloudExpressVAppTemplateHandler;
import com.google.common.util.concurrent.ListenableFuture;
@ -59,86 +86,278 @@ public interface SymphonyVPDCAsyncClient extends VCloudExpressAsyncClient {
/**
* {@inheritDoc}
*/
// savvis doesn't work with accept header
@Override
@GET
// no accept header
@XMLResponseParser(OrgHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends Org> findOrgNamed(
@Nullable @EndpointParam(parser = OrgNameToEndpoint.class) String orgName);
@Nullable @EndpointParam(parser = OrgNameToEndpoint.class) String orgName);
/**
* {@inheritDoc}
*/
// savvis doesn't work with accept header
@Override
@GET
// no accept header
@XMLResponseParser(OrgHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends Org> getOrg(@EndpointParam URI orgId);
/**
* @see CommonVCloudClient#getVDC(URI)
*/
@GET
@XMLResponseParser(VDCHandler.class)
// no accept header
@XMLResponseParser(SymphonyVPDCVDCHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VDC> getVDC(@EndpointParam URI vdc);
@Override
ListenableFuture<? extends SymphonyVPDCVDC> getVDC(@EndpointParam URI vdc);
/**
* @see CommonVCloudClient#findVDCInOrgNamed(String, String)
*/
@GET
@XMLResponseParser(VDCHandler.class)
// no accept header
@XMLResponseParser(SymphonyVPDCVDCHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VDC> findVDCInOrgNamed(
@Nullable @EndpointParam(parser = OrgNameAndVDCNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameAndVDCNameToEndpoint.class) String vdcName);
/**
* @see CommonVCloudClient#findNetworkInOrgVDCNamed
*//*
@GET
@XMLResponseParser(TerremarkOrgNetworkFromTerremarkVCloudExpressNetworkHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends OrgNetwork> findNetworkInOrgVDCNamed(
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String networkName);
@Override
ListenableFuture<? extends SymphonyVPDCVDC> findVDCInOrgNamed(
@Nullable @EndpointParam(parser = OrgNameAndVDCNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameAndVDCNameToEndpoint.class) String vdcName);
*//**
* @see CommonVCloudClient#getNetwork
*//*
@GET
@XMLResponseParser(TerremarkOrgNetworkFromTerremarkVCloudExpressNetworkHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends OrgNetwork> getNetwork(@EndpointParam URI network);*/
/**
* @see CommonVCloudClient#findNetworkInOrgVDCNamed
*/
@GET
// no accept header
@XMLResponseParser(SymphonyVPDCNetworkHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends OrgNetwork> findNetworkInOrgVDCNamed(
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String networkName);
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String networkName);
/**
* @see CommonVCloudClient#getNetwork
*/
@GET
// no accept header
@XMLResponseParser(SymphonyVPDCNetworkHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends OrgNetwork> getNetwork(@EndpointParam URI network);
/**
* @see VCloudClient#getVApp
*/
@GET
// no accept header
@XMLResponseParser(SymphonyVPDCVAppHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends VCloudExpressVApp> getVApp(@EndpointParam URI vApp);
/**
* @see VCloudClient#getVAppTemplate
*/
@GET
// no accept header
@XMLResponseParser(VCloudExpressVAppTemplateHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends VCloudExpressVAppTemplate> getVAppTemplate(@EndpointParam URI vAppTemplate);
/**
* @see VCloudClient#findVAppTemplateInOrgCatalogNamed
*/
@GET
// no accept header
@XMLResponseParser(VCloudExpressVAppTemplateHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends VCloudExpressVAppTemplate> findVAppTemplateInOrgCatalogNamed(
@Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameCatalogNameVAppTemplateNameToEndpoint.class) String itemName);
/**
* @see VCloudExpressClient#instantiateVAppTemplateInVDC
*/
@POST
@Path("/action/instantiateVAppTemplate")
@Produces("application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml")
// no accept header
@XMLResponseParser(VCloudExpressVAppHandler.class)
@MapBinder(BindInstantiateVCloudExpressVAppTemplateParamsToXmlPayload.class)
@Override
ListenableFuture<? extends VCloudExpressVApp> instantiateVAppTemplateInVDC(@EndpointParam URI vdc,
@PayloadParam("template") URI template,
@PayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName,
InstantiateVAppTemplateOptions... options);
/**
* @see VCloudExpressClient#cloneVAppInVDC
*/
@POST
@Path("/action/cloneVApp")
@Produces("application/vnd.vmware.vcloud.cloneVAppParams+xml")
// no accept header
@XMLResponseParser(TaskHandler.class)
@MapBinder(BindCloneVAppParamsToXmlPayload.class)
@Override
ListenableFuture<? extends Task> cloneVAppInVDC(@EndpointParam URI vdc, @PayloadParam("vApp") URI toClone,
@PayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, CloneVAppOptions... options);
/**
* @see VCloudClient#findVAppInOrgVDCNamed
*/
@GET
// no accept header
@XMLResponseParser(VCloudExpressVAppHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends VCloudExpressVApp> findVAppInOrgVDCNamed(
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String vAppName);
/**
* @see CommonVCloudClient#deployVApp
*/
@POST
// no accept header
@Path("/action/deploy")
@XMLResponseParser(TaskHandler.class)
@Override
ListenableFuture<? extends Task> deployVApp(@EndpointParam URI vAppId);
/**
* @see CommonVCloudClient#undeployVApp
*/
@POST
// no accept header
@Path("/action/undeploy")
@XMLResponseParser(TaskHandler.class)
@Override
ListenableFuture<? extends Task> undeployVApp(@EndpointParam URI vAppId);
/**
* @see CommonVCloudClient#powerOnVApp
*/
@POST
// no accept header
@Path("/power/action/powerOn")
@XMLResponseParser(TaskHandler.class)
@Override
ListenableFuture<? extends Task> powerOnVApp(@EndpointParam URI vAppId);
/**
* @see CommonVCloudClient#powerOffVApp
*/
@POST
// no accept header
@Path("/power/action/powerOff")
@XMLResponseParser(TaskHandler.class)
@Override
ListenableFuture<? extends Task> powerOffVApp(@EndpointParam URI vAppId);
/**
* @see CommonVCloudClient#resetVApp
*/
@POST
// no accept header
@Path("/power/action/reset")
@XMLResponseParser(TaskHandler.class)
@Override
ListenableFuture<? extends Task> resetVApp(@EndpointParam URI vAppId);
/**
* @see CommonVCloudClient#suspendVApp
*/
@POST
// no accept header
@Path("/power/action/suspend")
@XMLResponseParser(TaskHandler.class)
@Override
ListenableFuture<? extends Task> suspendVApp(@EndpointParam URI vAppId);
/**
* @see CommonVCloudClient#getCatalog
*/
@GET
@XMLResponseParser(CatalogHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
// no accept header
@Override
ListenableFuture<? extends Catalog> getCatalog(@EndpointParam URI catalogId);
/**
* @see CommonVCloudClient#findCatalogInOrgNamed
*/
@GET
@XMLResponseParser(CatalogHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
// no accept header
@Override
ListenableFuture<? extends Catalog> findCatalogInOrgNamed(
@Nullable @EndpointParam(parser = OrgNameAndCatalogNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameAndCatalogNameToEndpoint.class) String catalogName);
/**
* @see CommonVCloudClient#getCatalogItem
*/
@GET
// no accept header
@XMLResponseParser(CatalogItemHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends CatalogItem> getCatalogItem(@EndpointParam URI catalogItem);
/**
* @see CommonVCloudClient#getCatalogItemInOrg
*/
@GET
// no accept header
@XMLResponseParser(CatalogItemHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends CatalogItem> findCatalogItemInOrgCatalogNamed(
@Nullable @EndpointParam(parser = OrgNameCatalogNameItemNameToEndpoint.class) String orgName,
@Nullable @EndpointParam(parser = OrgNameCatalogNameItemNameToEndpoint.class) String catalogName,
@EndpointParam(parser = OrgNameCatalogNameItemNameToEndpoint.class) String itemName);
/**
* @see CommonVCloudClient#getTasksList
*/
@GET
// no accept header
@XMLResponseParser(TasksListHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends TasksList> getTasksList(@EndpointParam URI tasksListId);
/**
* @see CommonVCloudClient#findTasksListInOrgNamed
*/
@GET
// no accept header
@XMLResponseParser(TasksListHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends TasksList> findTasksListInOrgNamed(
@Nullable @EndpointParam(parser = OrgNameToTasksListEndpoint.class) String orgName);
/**
* @see CommonVCloudClient#getTask
*/
@GET
// no accept header
@XMLResponseParser(TaskHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Override
ListenableFuture<? extends Task> getTask(@EndpointParam URI taskId);
}

View File

@ -19,9 +19,11 @@
package org.jclouds.savvis.vpdc;
import java.net.URI;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.savvis.vpdc.domain.SymphonyVPDCVDC;
import org.jclouds.vcloud.VCloudExpressClient;
/**
@ -33,5 +35,9 @@ import org.jclouds.vcloud.VCloudExpressClient;
*/
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface SymphonyVPDCClient extends VCloudExpressClient {
@Override
SymphonyVPDCVDC findVDCInOrgNamed(String orgName, String vdcName);
@Override
SymphonyVPDCVDC getVDC(URI vdc);
}

View File

@ -0,0 +1,34 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.savvis.vpdc.domain;
import org.jclouds.savvis.vpdc.domain.internal.SymphonyVPDCVDCImpl;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.VDC;
import com.google.inject.ImplementedBy;
/**
* @author Adrian Cole
*/
@ImplementedBy(SymphonyVPDCVDCImpl.class)
public interface SymphonyVPDCVDC extends VDC {
String getOfferingTag();
}

View File

@ -0,0 +1,75 @@
package org.jclouds.savvis.vpdc.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import javax.annotation.Nullable;
import org.jclouds.savvis.vpdc.domain.SymphonyVPDCVDC;
import org.jclouds.vcloud.domain.AllocationModel;
import org.jclouds.vcloud.domain.Capacity;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VDCStatus;
import org.jclouds.vcloud.domain.internal.VDCImpl;
/**
* Locations of resources in SymphonyVPDC vDC
*
* @author Adrian Cole
*
*/
public class SymphonyVPDCVDCImpl extends VDCImpl implements SymphonyVPDCVDC {
private final String offeringTag;
/** The serialVersionUID */
private static final long serialVersionUID = 8464716396538298809L;
public SymphonyVPDCVDCImpl(String name, String type, URI id, VDCStatus status, ReferenceType org,
@Nullable String description, Iterable<Task> tasks, AllocationModel allocationModel,
@Nullable Capacity storageCapacity, @Nullable Capacity cpuCapacity, @Nullable Capacity memoryCapacity,
Map<String, ReferenceType> resourceEntities, Map<String, ReferenceType> availableNetworks, int nicQuota,
int networkQuota, int vmQuota, boolean isEnabled, String offeringTag) {
super(name, type, id, status, org, description, tasks, allocationModel, storageCapacity, cpuCapacity,
memoryCapacity, resourceEntities, availableNetworks, nicQuota, networkQuota, vmQuota, isEnabled);
this.offeringTag = checkNotNull(offeringTag, "offeringTag");
}
@Override
public String getOfferingTag() {
return offeringTag;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((offeringTag == null) ? 0 : offeringTag.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
SymphonyVPDCVDCImpl other = (SymphonyVPDCVDCImpl) obj;
if (offeringTag == null) {
if (other.offeringTag != null)
return false;
} else if (!offeringTag.equals(other.offeringTag))
return false;
return true;
}
@Override
public String toString() {
return "[id=" + getHref() + ", name=" + getName() + ", description=" + getDescription() + ", offeringTag="
+ offeringTag + "]";
}
}

View File

@ -0,0 +1,58 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.savvis.vpdc.xml;
import javax.inject.Inject;
import org.jclouds.savvis.vpdc.domain.SymphonyVPDCVDC;
import org.jclouds.savvis.vpdc.domain.internal.SymphonyVPDCVDCImpl;
import org.jclouds.vcloud.domain.VDC;
import org.jclouds.vcloud.xml.TaskHandler;
import org.jclouds.vcloud.xml.VDCHandler;
/**
* @author Adrian Cole
*/
public class SymphonyVPDCVDCHandler extends VDCHandler {
@Inject
public SymphonyVPDCVDCHandler(TaskHandler taskHandler) {
super(taskHandler);
}
private String offeringTag;
public SymphonyVPDCVDC getResult() {
VDC vDC = super.getResult();
return new SymphonyVPDCVDCImpl(vDC.getName(), vDC.getType(), vDC.getHref(), status, org, description, tasks,
allocationModel, storageCapacity, cpuCapacity, memoryCapacity, resourceEntities, availableNetworks,
nicQuota, networkQuota, vmQuota, isEnabled, offeringTag);
}
@Override
public void endElement(String uri, String name, String qName) {
if (qName.endsWith("OfferingTag")) {
this.offeringTag = currentOrNull();
}
super.endElement(uri, name, qName);
}
}

View File

@ -50,9 +50,9 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.savvis.vpdc.config.SymphonyVPDCRestClientModule;
import org.jclouds.savvis.vpdc.xml.SymphonyVPDCNetworkHandler;
import org.jclouds.savvis.vpdc.xml.SymphonyVPDCVAppHandler;
import org.jclouds.savvis.vpdc.xml.SymphonyVPDCVDCHandler;
import org.jclouds.util.Strings2;
import org.jclouds.vcloud.CommonVCloudClient;
import org.jclouds.vcloud.VCloudExpressAsyncClient;
import org.jclouds.vcloud.VCloudExpressLoginAsyncClient;
import org.jclouds.vcloud.VCloudExpressMediaType;
import org.jclouds.vcloud.VCloudVersionsAsyncClient;
@ -77,7 +77,6 @@ import org.jclouds.vcloud.xml.TaskHandler;
import org.jclouds.vcloud.xml.TasksListHandler;
import org.jclouds.vcloud.xml.VCloudExpressVAppHandler;
import org.jclouds.vcloud.xml.VCloudExpressVAppTemplateHandler;
import org.jclouds.vcloud.xml.VDCHandler;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
@ -104,7 +103,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vdc/1/action/instantiateVAppTemplate HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(
request,
Strings2.toStringAndClose(getClass().getResourceAsStream("/express/newvapp-hosting.xml")).replace(
@ -136,7 +135,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vdc/1/action/instantiateVAppTemplate HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request,
Strings2.toStringAndClose(getClass().getResourceAsStream("/express/newvapp-hostingcpumemdisk.xml"))
.replace("vcloud.safesecureweb.com/api", "api.sandbox.symphonyVPDC.savvis.net/rest/api"),
@ -176,7 +175,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vdc/1/action/cloneVApp HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(
request,
Strings2.toStringAndClose(getClass().getResourceAsStream("/express/cloneVApp-default.xml")).replace(
@ -200,7 +199,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vdc/1/action/cloneVApp HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/express/cloneVApp.xml"))
.replace("vcloud.safesecureweb.com/api", "api.sandbox.symphonyVPDC.savvis.net/rest/api"),
"application/vnd.vmware.vcloud.cloneVAppParams+xml", false);
@ -250,7 +249,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"GET https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/catalog/1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalog+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -266,7 +265,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"GET https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/catalog/1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalog+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -300,7 +299,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"GET https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/catalogItem/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalogItem+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -317,7 +316,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"GET https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/catalogItem/1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalogItem+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -334,7 +333,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"GET https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vAppTemplate/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vAppTemplate+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -351,7 +350,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"GET https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vAppTemplate/2 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vAppTemplate+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -370,7 +369,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VDCHandler.class);
assertSaxResponseParserClassEquals(method, SymphonyVPDCVDCHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
@ -397,7 +396,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VDCHandler.class);
assertSaxResponseParserClassEquals(method, SymphonyVPDCVDCHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
@ -412,7 +411,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VDCHandler.class);
assertSaxResponseParserClassEquals(method, SymphonyVPDCVDCHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
@ -428,7 +427,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VDCHandler.class);
assertSaxResponseParserClassEquals(method, SymphonyVPDCVDCHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
@ -441,7 +440,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"GET https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/tasksList/1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.tasksList+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -452,12 +451,12 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
}
public void testFindTasksListInOrgNamed() throws SecurityException, NoSuchMethodException, IOException {
Method method = VCloudExpressAsyncClient.class.getMethod("findTasksListInOrgNamed", String.class);
Method method = SymphonyVPDCAsyncClient.class.getMethod("findTasksListInOrgNamed", String.class);
HttpRequest request = processor.createRequest(method, "org");
assertRequestLineEquals(request,
"GET https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/tasksList/1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.tasksList+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -474,7 +473,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vApp/1/action/deploy HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -507,7 +506,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vApp/1/action/undeploy HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -541,7 +540,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vApp/1/power/action/powerOn HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -558,7 +557,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vApp/1/power/action/powerOff HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -575,7 +574,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vApp/1/power/action/reset HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -592,7 +591,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
assertRequestLineEquals(request,
"POST https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/vApp/1/power/action/suspend HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -625,7 +624,7 @@ public class SymphonyVPDCAsyncClientTest extends RestClientTest<SymphonyVPDCAsyn
URI.create("https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/task/1"));
assertRequestLineEquals(request, "GET https://api.sandbox.symphonyVPDC.savvis.net/rest/api/v0.8/task/1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);

View File

@ -19,14 +19,48 @@
package org.jclouds.savvis.vpdc;
import static com.google.common.collect.Iterables.find;
import static org.jclouds.vcloud.options.CloneVAppOptions.Builder.deploy;
import static org.jclouds.vcloud.predicates.VCloudPredicates.resourceType;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.URI;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshClient.Factory;
import org.jclouds.ssh.SshException;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.VCloudExpressClientLiveTest;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Status;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VCloudExpressVApp;
import org.jclouds.vcloud.domain.VCloudExpressVAppTemplate;
import org.jclouds.vcloud.domain.VDC;
import org.jclouds.vcloud.domain.ovf.ResourceType;
import org.jclouds.vcloud.options.CloneVAppOptions;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import org.jclouds.vcloud.predicates.TaskSuccess;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.Injector;
import com.google.inject.Module;
public class SymphonyVPDCClientLiveTest extends VCloudExpressClientLiveTest {
@ -46,9 +80,247 @@ public class SymphonyVPDCClientLiveTest extends VCloudExpressClientLiveTest {
restProperties.setProperty("savvis-symphony-vpdc.propertiesbuilder",
SymphonyVPDCPropertiesBuilder.class.getName());
context = new ComputeServiceContextFactory(restProperties).createContext(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
Injector injector = new RestContextFactory(restProperties).createContextBuilder(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides).buildInjector();
connection = injector.getInstance(SymphonyVPDCClient.class);
sshFactory = injector.getInstance(SshClient.Factory.class);
socketTester = new RetryablePredicate<IPSocket>(injector.getInstance(SocketOpen.class), 130, 10, TimeUnit.SECONDS);// make
// it
// longer
// then
// default internet
// service timeout
successTester = new RetryablePredicate<URI>(injector.getInstance(TaskSuccess.class), 650, 10, TimeUnit.SECONDS);
}
protected String expectedOs = "Ubuntu Linux (64-bit)";
protected String itemName = "Ubuntu JeOS 9.10 (64-bit)";
protected Factory sshFactory;
private VCloudExpressVApp vApp;
private RetryablePredicate<IPSocket> socketTester;
private RetryablePredicate<URI> successTester;
private VCloudExpressVApp clone;
private VDC vdc;
public static final String PREFIX = System.getProperty("user.name") + "-savvis";
@Test(enabled = true)
public void testInstantiateAndPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
prepare();
StringBuffer name = new StringBuffer();
for (int i = 0; i < 15; i++)
name.append("c");
String serverName = name.toString();// "adriantest";
long hardDisk = 4194304;
// long hardDisk = 4194304 / 4 * 10;
// String catalogOs = "CentOS 5.3 (64-bit)";
// String expectedOs = "Red Hat Enterprise Linux 5 (64-bit)";
// lookup the datacenter you are deploying into
vdc = connection.findVDCInOrgNamed(null, null);
ReferenceType vAppTemplateId = Iterables.find(vdc.getResourceEntities().values(), new Predicate<ReferenceType>() {
@Override
public boolean apply(ReferenceType arg0) {
return arg0.getType().equals(VCloudMediaType.VAPPTEMPLATE_XML);
}
});
VCloudExpressVAppTemplate vAppTemplate = connection.getVAppTemplate(vAppTemplateId.getHref());
assert vAppTemplate != null;
// create an options object to collect the configuration we want.
InstantiateVAppTemplateOptions instantiateOptions = new InstantiateVAppTemplateOptions();
// instantiate, noting vApp returned has minimal details
vApp = connection.instantiateVAppTemplateInVDC(vdc.getHref(), vAppTemplate.getHref(), serverName,
instantiateOptions);
assertEquals(vApp.getStatus(), Status.RESOLVED);
Task deployTask = connection.deployVApp(vApp.getHref());
// check to see the result of calling deploy twice
deployTask = connection.deployVApp(vApp.getHref());
assertEquals(deployTask.getHref(), deployTask.getHref());
vApp = connection.getVApp(vApp.getHref());
assertEquals(vApp.getStatus(), Status.RESOLVED);
try {// per docs, this is not supported
connection.cancelTask(deployTask.getHref());
} catch (UnsupportedOperationException e) {
}
assert successTester.apply(deployTask.getHref());
System.out.printf("%d: done deploying vApp%n", System.currentTimeMillis());
vApp = connection.getVApp(vApp.getHref());
ReferenceType vAppResource = connection.findVDCInOrgNamed(null, null).getResourceEntities().get(serverName);
assertEquals(vAppResource.getHref(), vApp.getHref());
int processorCount = 1;
long memory = 512;
verifyConfigurationOfVApp(vApp, serverName, expectedOs, processorCount, memory, hardDisk);
assertEquals(vApp.getStatus(), Status.OFF);
assert successTester.apply(connection.powerOnVApp(vApp.getHref()).getHref());
System.out.printf("%d: done powering on vApp%n", System.currentTimeMillis());
vApp = connection.getVApp(vApp.getHref());
assertEquals(vApp.getStatus(), Status.ON);
}
protected void prepare() {
}
@Test(enabled = true, dependsOnMethods = "testInstantiateAndPowerOn")
public void testCloneVApp() throws IOException {
assert successTester.apply(connection.powerOffVApp(vApp.getHref()).getHref());
System.out.printf("%d: done powering off vApp%n", System.currentTimeMillis());
StringBuffer name = new StringBuffer();
for (int i = 0; i < 15; i++)
name.append("b");
String newName = name.toString();
CloneVAppOptions options = deploy().powerOn().withDescription("The description of " + newName);
System.out.printf("%d: cloning vApp%n", System.currentTimeMillis());
Task task = connection.cloneVAppInVDC(vdc.getHref(), vApp.getHref(), newName, options);
// wait for the task to complete
assert successTester.apply(task.getHref());
System.out.printf("%d: done cloning vApp%n", System.currentTimeMillis());
assert successTester.apply(connection.powerOnVApp(vApp.getHref()).getHref());
System.out.printf("%d: done powering on vApp%n", System.currentTimeMillis());
// refresh task to get the new vApp location
task = connection.getTask(task.getHref());
clone = connection.getVApp(task.getOwner().getHref());
assertEquals(clone.getStatus(), Status.ON);
assertEquals(clone.getName(), newName);
assertEquals(clone.getNetworkToAddresses().values().size(), 1);
}
private void loopAndCheckPass(String publicIp) throws IOException {
for (int i = 0; i < 5; i++) {// retry loop TODO replace with predicate.
try {
doCheckPass(publicIp);
return;
} catch (SshException e) {
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e1) {
}
continue;
}
}
}
@Test(enabled = true, dependsOnMethods = "testCloneVApp")
public void testLifeCycle() throws InterruptedException, ExecutionException, TimeoutException, IOException {
try {// per docs, this is not supported
connection.undeployVApp(vApp.getHref());
assert false;
} catch (UnsupportedOperationException e) {
}
try {// per docs, this is not supported
connection.suspendVApp(vApp.getHref());
assert false;
} catch (UnsupportedOperationException e) {
}
assert successTester.apply(connection.resetVApp(vApp.getHref()).getHref());
vApp = connection.getVApp(vApp.getHref());
assertEquals(vApp.getStatus(), Status.ON);
// TODO we need to determine whether shutdown is supported before invoking
// it.
// connection.shutdownVApp(vApp.getId());
// vApp = connection.getVApp(vApp.getId());
// assertEquals(vApp.getStatus(), VAppStatus.ON);
assert successTester.apply(connection.powerOffVApp(vApp.getHref()).getHref());
vApp = connection.getVApp(vApp.getHref());
assertEquals(vApp.getStatus(), Status.OFF);
}
private void verifyConfigurationOfVApp(VCloudExpressVApp vApp, String serverName, String expectedOs,
int processorCount, long memory, long hardDisk) {
assertEquals(vApp.getName(), serverName);
assertEquals(vApp.getOperatingSystemDescription(), expectedOs);
assertEquals(find(vApp.getResourceAllocations(), resourceType(ResourceType.PROCESSOR)).getVirtualQuantity(),
processorCount);
assertEquals(
find(vApp.getResourceAllocations(), resourceType(ResourceType.SCSI_CONTROLLER)).getVirtualQuantity(), 1);
assertEquals(find(vApp.getResourceAllocations(), resourceType(ResourceType.MEMORY)).getVirtualQuantity(), memory);
assertEquals(find(vApp.getResourceAllocations(), resourceType(ResourceType.DISK_DRIVE)).getVirtualQuantity(),
hardDisk);
assertEquals(vApp.getSize().longValue(),
find(vApp.getResourceAllocations(), resourceType(ResourceType.DISK_DRIVE)).getVirtualQuantity());
}
private void doCheckPass(String address) throws IOException {
IPSocket socket = new IPSocket(address, 22);
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(), socket);
assert socketTester.apply(socket);
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), socket);
SshClient connection = getConnectionFor(socket);
try {
connection.connect();
System.out.printf("%d: %s ssh connection made%n", System.currentTimeMillis(), socket);
System.out.println(connection.exec("df -h"));
} finally {
if (connection != null)
connection.disconnect();
}
}
protected SshClient getConnectionFor(IPSocket socket) {
// TODO add in the correct login credentials for the vApp template
return sshFactory.create(socket, new Credentials("root", "password"));
}
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (vApp != null) {
try {
successTester.apply(connection.powerOffVApp(vApp.getHref()).getHref());
} catch (Exception e) {
}
connection.deleteVApp(vApp.getHref());
}
if (clone != null) {
try {
successTester.apply(connection.powerOffVApp(clone.getHref()).getHref());
} catch (Exception e) {
}
connection.deleteVApp(clone.getHref());
}
connection = context.getApi();
}
}

View File

@ -32,7 +32,7 @@ import org.testng.annotations.Test;
*
* @author Kedar Dave
*/
@Test(groups = "live", enabled = true, sequential = true)
@Test(groups = "live", enabled = false, sequential = true)
public class SymphonyVPDCComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public SymphonyVPDCComputeServiceLiveTest() {
provider = "savvis-symphony-vpdc";

View File

@ -28,7 +28,7 @@ import com.google.inject.Module;
*
* @author Adrian Cole
*/
@Test(groups = "live")
@Test(groups = "live", enabled = false)
public class SymphonyVPDCTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
public SymphonyVPDCTemplateBuilderLiveTest() {

View File

@ -0,0 +1,66 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.savvis.vpdc.xml;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.URI;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseSax.Factory;
import org.jclouds.http.functions.config.SaxParserModule;
import org.jclouds.vcloud.domain.Org;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.internal.OrgImpl;
import org.jclouds.vcloud.domain.internal.ReferenceTypeImpl;
import org.jclouds.vcloud.xml.OrgHandler;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code OrgHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class OrgHandlerTest {
public void testSavvis() {
InputStream is = getClass().getResourceAsStream("/savvis/org.xml");
Injector injector = Guice.createInjector(new SaxParserModule());
Factory factory = injector.getInstance(ParseSax.Factory.class);
Org result = (Org) factory.create(injector.getInstance(OrgHandler.class)).parse(is);
assertEquals(
result,
new OrgImpl("100000.0", null, null, "100000.0", "SAVVISStation Integration Testing", ImmutableMap
.<String, ReferenceType> of(), ImmutableMap.<String, ReferenceType> of(
"demo_vpdcname",
new ReferenceTypeImpl("demo_vpdcname", "application/vnd.vmware.vcloud.vdc+xml", URI
.create("https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736"))),
ImmutableMap.<String, ReferenceType> of(), null, ImmutableSet.<Task> of()));
}
}

View File

@ -0,0 +1,93 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.savvis.vpdc.xml;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.URI;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseSax.Factory;
import org.jclouds.http.functions.config.SaxParserModule;
import org.jclouds.savvis.vpdc.domain.SymphonyVPDCVDC;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.internal.ReferenceTypeImpl;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code SymphonyVPDCVDCHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class SymphonyVPDCVDCHandlerTest {
public void test() {
InputStream is = getClass().getResourceAsStream("/savvis/vdc.xml");
Injector injector = Guice.createInjector(new SaxParserModule());
Factory factory = injector.getInstance(ParseSax.Factory.class);
SymphonyVPDCVDC result = (SymphonyVPDCVDC) factory.create(injector.getInstance(SymphonyVPDCVDCHandler.class))
.parse(is);
assertEquals(result.getName(), "demo_vpdcname");
assertEquals(result.getHref(), null);
assertEquals(result.getDescription(),
"ServiceProfileName = Balanced; ServiceLocation = North America; Email = jim@company.com;");
assertEquals(result.getOfferingTag(), "Deployed");
assertEquals(result.getStorageCapacity(), null);
assertEquals(result.getCpuCapacity(), null);
assertEquals(result.getMemoryCapacity(), null);
assertEquals(result.getVmQuota(), 0);
assertEquals(
result.getResourceEntities(),
ImmutableMap.<String, ReferenceType> of(
"DemoHost-1",
new ReferenceTypeImpl(
"DemoHost-1",
VCloudMediaType.VAPP_XML,
URI.create("https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/vApp/1001")),
"DemoHost-2",
new ReferenceTypeImpl(
"DemoHost-2",
VCloudMediaType.VAPP_XML,
URI.create("https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/vApp/1002")),
"DemoHost-3",
new ReferenceTypeImpl(
"DemoHost-3",
VCloudMediaType.VAPP_XML,
URI.create("https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/vApp/1003")),
"CustomerTemplateName",
new ReferenceTypeImpl(
"CustomerTemplateName",
VCloudMediaType.VAPPTEMPLATE_XML,
URI.create("https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/vAppTemplate/1234")),
"firewall",
new ReferenceTypeImpl(
"firewall",
"api.sandbox.symphonyVPDC.savvis.net+xml",
URI.create("https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/FirewallService"))));
assertEquals(result.getAvailableNetworks(), ImmutableMap.of());
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<vApp:Org xmlns:common="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:vApp="http://www.vmware.com/vcloud/v0.8" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" name="100000.0">
<vApp:Link name="demo_vpdcname" type="application/vnd.vmware.vcloud.vdc+xml" href="https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736" rel="down"/>
<vApp:Description>SAVVISStation Integration Testing</vApp:Description>
</vApp:Org>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<vApp:Vdc xmlns:common="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:vApp="http://www.vmware.com/vcloud/v0.8" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" name="demo_vpdcname" type="application/vnd.vmware.vcloud.vdc+xml">
<vApp:Description>ServiceProfileName = Balanced; ServiceLocation = North America; Email = jim@company.com;</vApp:Description>
<vApp:OfferingTag>Deployed</vApp:OfferingTag>
<vApp:ResourceEntities>
<vApp:ResourceEntity name="DemoHost-1" type="application/vnd.vmware.vcloud.vApp+xml" href="https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/vApp/1001"/>
<vApp:ResourceEntity name="DemoHost-2" type="application/vnd.vmware.vcloud.vApp+xml" href="https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/vApp/1002"/>
<vApp:ResourceEntity name="DemoHost-3" type="application/vnd.vmware.vcloud.vApp+xml" href="https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/vApp/1003"/>
<vApp:ResourceEntity name="CustomerTemplateName" type="application/vnd.vmware.vcloud.vAppTemplate+xml" href="https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/vAppTemplate/1234"/>
<vApp:ResourceEntity name="firewall" type="api.sandbox.symphonyVPDC.savvis.net+xml" href="https://api.sandbox.symphonyvpdc.savvis.net/rest/api/v0.8/org/100000.0/vdc/2736/FirewallService"/>
</vApp:ResourceEntities>
<vApp:AvailableNetworks/>
</vApp:Vdc>

View File

@ -24,7 +24,7 @@ public class ServerManagerComputeServiceLiveTest extends BaseComputeServiceLiveT
}
@Override
protected Properties getRestProperties() {
protected Properties setupRestProperties() {
Properties restProperties = new Properties();
restProperties.setProperty("servermanager.contextbuilder",
ServerManagerComputeServiceContextBuilder.class.getName());