Issue 327: converted to URI id for keypair operations in terremark; Issue 306: converted vcloud org commands to be name-based

This commit is contained in:
Adrian Cole 2010-08-08 13:12:52 -07:00
parent 664644534a
commit e2c5a546a8
27 changed files with 840 additions and 283 deletions

View File

@ -28,6 +28,7 @@ import static org.jclouds.vcloud.VCloudMediaType.VAPPTEMPLATE_XML;
import static org.jclouds.vcloud.VCloudMediaType.VAPP_XML;
import static org.jclouds.vcloud.VCloudMediaType.VDC_XML;
import javax.annotation.Nullable;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
@ -38,6 +39,7 @@ import javax.ws.rs.Produces;
import org.jclouds.predicates.validators.DnsNameValidator;
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.MapPayloadParam;
@ -60,6 +62,7 @@ import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.domain.VDC;
import org.jclouds.vcloud.endpoints.Org;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.functions.OrgNameToEndpoint;
import org.jclouds.vcloud.functions.VAppIdToUri;
import org.jclouds.vcloud.functions.VAppTemplateIdToUri;
import org.jclouds.vcloud.options.CloneVAppOptions;
@ -80,18 +83,26 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides access to VCloud resources via their REST API.
* <p/>
*
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx" />
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx"
* />
* @author Adrian Cole
*/
@RequestFilters(SetVCloudTokenCookie.class)
public interface VCloudAsyncClient {
/**
* @see VCloudClient#getDefaultOrganization
*/
@Deprecated
@GET
@Endpoint(Org.class)
@Consumes(ORG_XML)
@XMLResponseParser(OrgHandler.class)
ListenableFuture<? extends Organization> getDefaultOrganization();
/**
* @see VCloudClient#getOrganization
*/
@Deprecated
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/org/{orgId}")
@ -100,12 +111,28 @@ public interface VCloudAsyncClient {
@Consumes(ORG_XML)
ListenableFuture<? extends Organization> getOrganization(@PathParam("orgId") String orgId);
/**
* @see VCloudClient#getOrganizationNamed
*/
@GET
@XMLResponseParser(OrgHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(ORG_XML)
ListenableFuture<? extends Organization> getOrganizationNamed(
@Nullable @EndpointParam(parser = OrgNameToEndpoint.class) String orgName);
/**
* @see VCloudClient#getDefaultCatalog
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.Catalog.class)
@Consumes(CATALOG_XML)
@XMLResponseParser(CatalogHandler.class)
ListenableFuture<? extends Catalog> getDefaultCatalog();
/**
* @see VCloudClient#getCatalog
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/catalog/{catalogId}")
@ -114,24 +141,31 @@ public interface VCloudAsyncClient {
@Consumes(CATALOG_XML)
ListenableFuture<? extends Catalog> getCatalog(@PathParam("catalogId") String catalogId);
/**
* @see VCloudClient#getVAppTemplate
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/vAppTemplate/{vAppTemplateId}")
@Consumes(VAPPTEMPLATE_XML)
@XMLResponseParser(VAppTemplateHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VAppTemplate> getVAppTemplate(
@PathParam("vAppTemplateId") String vAppTemplateId);
ListenableFuture<? extends VAppTemplate> getVAppTemplate(@PathParam("vAppTemplateId") String vAppTemplateId);
/**
* @see VCloudClient#getCatalogItem
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/catalogItem/{catalogItemId}")
@Consumes(CATALOGITEM_XML)
@XMLResponseParser(CatalogItemHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends CatalogItem> getCatalogItem(
@PathParam("catalogItemId") String catalogItemId);
ListenableFuture<? extends CatalogItem> getCatalogItem(@PathParam("catalogItemId") String catalogItemId);
/**
* @see VCloudClient#getNetwork
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/network/{networkId}")
@ -140,12 +174,18 @@ public interface VCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends Network> getNetwork(@PathParam("networkId") String networkId);
/**
* @see VCloudClient#getDefaultVDC
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VDC.class)
@XMLResponseParser(VDCHandler.class)
@Consumes(VDC_XML)
ListenableFuture<? extends VDC> getDefaultVDC();
/**
* @see VCloudClient#getVDC
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/vdc/{vDCId}")
@ -154,6 +194,9 @@ public interface VCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VDC> getVDC(@PathParam("vDCId") String vDCId);
/**
* @see VCloudClient#getTasksList
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/tasksList/{tasksListId}")
@ -162,12 +205,18 @@ public interface VCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends TasksList> getTasksList(@PathParam("tasksListId") String tasksListId);
/**
* @see VCloudClient#getDefaultTasksList
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.TasksList.class)
@Consumes(TASKSLIST_XML)
@XMLResponseParser(TasksListHandler.class)
ListenableFuture<? extends TasksList> getDefaultTasksList();
/**
* @see VCloudClient#deployVApp
*/
@POST
@Consumes(TASK_XML)
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@ -175,12 +224,18 @@ public interface VCloudAsyncClient {
@XMLResponseParser(TaskHandler.class)
ListenableFuture<? extends Task> deployVApp(@PathParam("vAppId") String vAppId);
/**
* @see VCloudClient#deleteVApp
*/
@DELETE
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
@Path("/vApp/{vAppId}")
ListenableFuture<Void> deleteVApp(@PathParam("vAppId") String vAppId);
/**
* @see VCloudClient#undeployVApp
*/
@POST
@Consumes(TASK_XML)
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@ -189,7 +244,7 @@ public interface VCloudAsyncClient {
ListenableFuture<? extends Task> undeployVApp(@PathParam("vAppId") String vAppId);
/**
* This call powers on the vApp, as specified in the vApp's ovf:Startup element.
* @see VCloudClient#powerOnVApp
*/
@POST
@Consumes(TASK_XML)
@ -199,7 +254,7 @@ public interface VCloudAsyncClient {
ListenableFuture<? extends Task> powerOnVApp(@PathParam("vAppId") String vAppId);
/**
* This call powers off the vApp, as specified in the vApp's ovf:Startup element.
* @see VCloudClient#powerOffVApp
*/
@POST
@Consumes(TASK_XML)
@ -209,7 +264,7 @@ public interface VCloudAsyncClient {
ListenableFuture<? extends Task> powerOffVApp(@PathParam("vAppId") String vAppId);
/**
* This call shuts down the vApp.
* @see VCloudClient#shutdownVApp
*/
@POST
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@ -217,7 +272,7 @@ public interface VCloudAsyncClient {
ListenableFuture<Void> shutdownVApp(@PathParam("vAppId") String vAppId);
/**
* This call resets the vApp.
* @see VCloudClient#resetVApp
*/
@POST
@Consumes(TASK_XML)
@ -227,7 +282,7 @@ public interface VCloudAsyncClient {
ListenableFuture<? extends Task> resetVApp(@PathParam("vAppId") String vAppId);
/**
* This call suspends the vApp.
* @see VCloudClient#suspendVApp
*/
@POST
@Consumes(TASK_XML)
@ -236,6 +291,9 @@ public interface VCloudAsyncClient {
@XMLResponseParser(TaskHandler.class)
ListenableFuture<? extends Task> suspendVApp(@PathParam("vAppId") String vAppId);
/**
* @see VCloudClient#getTask
*/
@GET
@Consumes(TASK_XML)
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@ -244,11 +302,17 @@ public interface VCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends Task> getTask(@PathParam("taskId") String taskId);
/**
* @see VCloudClient#cancelTask
*/
@POST
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/task/{taskId}/action/cancel")
ListenableFuture<Void> cancelTask(@PathParam("taskId") String taskId);
/**
* @see VCloudClient#getVApp
*/
@GET
@Consumes(VAPP_XML)
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@ -257,6 +321,9 @@ public interface VCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VApp> getVApp(@PathParam("vAppId") String appId);
/**
* @see VCloudClient#instantiateVAppTemplateInVDC
*/
@POST
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/vdc/{vDCId}/action/instantiateVAppTemplate")
@ -265,10 +332,13 @@ public interface VCloudAsyncClient {
@XMLResponseParser(VAppHandler.class)
@MapBinder(BindInstantiateVAppTemplateParamsToXmlPayload.class)
ListenableFuture<? extends VApp> instantiateVAppTemplateInVDC(@PathParam("vDCId") String vDCId,
@MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName,
@MapPayloadParam("template") @ParamParser(VAppTemplateIdToUri.class) String templateId,
InstantiateVAppTemplateOptions... options);
@MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName,
@MapPayloadParam("template") @ParamParser(VAppTemplateIdToUri.class) String templateId,
InstantiateVAppTemplateOptions... options);
/**
* @see VCloudClient#cloneVAppInVDC
*/
@POST
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/vdc/{vDCId}/action/cloneVApp")
@ -277,7 +347,7 @@ public interface VCloudAsyncClient {
@XMLResponseParser(TaskHandler.class)
@MapBinder(BindCloneVAppParamsToXmlPayload.class)
ListenableFuture<? extends Task> cloneVAppInVDC(@PathParam("vDCId") String vDCId,
@MapPayloadParam("vApp") @ParamParser(VAppIdToUri.class) String vAppIdToClone,
@MapPayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName,
CloneVAppOptions... options);
@MapPayloadParam("vApp") @ParamParser(VAppIdToUri.class) String vAppIdToClone,
@MapPayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName,
CloneVAppOptions... options);
}

View File

@ -37,21 +37,35 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
* Provides access to VCloud resources via their REST API.
* <p/>
*
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx" />
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx"
* />
* @author Adrian Cole
*/
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface VCloudClient {
/**
* This call returns a list of all vCloud Data Centers (vdcs), catalogs, and task lists within
* the organization.
* Please use {@link #getOrganizationNamed(String)} passing null
*/
@Deprecated
Organization getDefaultOrganization();
/**
* Please use #getOrganizationByName
*/
@Deprecated
Organization getOrganization(String orgId);
/**
* This call returns a list of all vCloud Data Centers (vdcs), catalogs, and
* task lists within the organization.
*
* @param name
* organization name, or null for the default
*/
Organization getOrganizationNamed(String name);
Catalog getDefaultCatalog();
Catalog getCatalog(String catalogId);
CatalogItem getCatalogItem(String catalogItemId);
@ -75,12 +89,14 @@ public interface VCloudClient {
Task undeployVApp(String vAppId);
/**
* This call powers on the vApp, as specified in the vApp's ovf:Startup element.
* This call powers on the vApp, as specified in the vApp's ovf:Startup
* element.
*/
Task powerOnVApp(String vAppId);
/**
* This call powers off the vApp, as specified in the vApp's ovf:Startup element.
* This call powers off the vApp, as specified in the vApp's ovf:Startup
* element.
*/
Task powerOffVApp(String vAppId);
@ -106,8 +122,7 @@ public interface VCloudClient {
VApp getVApp(String appId);
VApp instantiateVAppTemplateInVDC(String vDCId, String appName, String templateId,
InstantiateVAppTemplateOptions... options);
InstantiateVAppTemplateOptions... options);
Task cloneVAppInVDC(String vDCId, String vAppIdToClone, String newName,
CloneVAppOptions... options);
Task cloneVAppInVDC(String vDCId, String vAppIdToClone, String newName, CloneVAppOptions... options);
}

View File

@ -57,8 +57,7 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
protected final Map<VAppStatus, NodeState> vAppStatusToNodeState;
@Inject
public BaseVCloudComputeClient(VCloudClient client,
Predicate<String> successTester,
public BaseVCloudComputeClient(VCloudClient client, Predicate<String> successTester,
Map<VAppStatus, NodeState> vAppStatusToNodeState) {
this.client = client;
this.taskTester = successTester;
@ -66,16 +65,13 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
}
@Override
public Map<String, String> start(String vDCId, String name,
String templateId, InstantiateVAppTemplateOptions options,
int... portsToOpen) {
public Map<String, String> start(String vDCId, String name, String templateId,
InstantiateVAppTemplateOptions options, int... portsToOpen) {
checkNotNull(options, "options");
logger.debug(
">> instantiating vApp vDC(%s) name(%s) template(%s) options(%s) ",
vDCId, name, templateId, options);
logger
.debug(">> instantiating vApp vDC(%s) name(%s) template(%s) options(%s) ", vDCId, name, templateId, options);
VApp vAppResponse = client.instantiateVAppTemplateInVDC(vDCId, name,
templateId, options);
VApp vAppResponse = client.instantiateVAppTemplateInVDC(vDCId, name, templateId, options);
logger.debug("<< instantiated VApp(%s)", vAppResponse.getId());
logger.debug(">> deploying vApp(%s)", vAppResponse.getId());
@ -97,20 +93,15 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
return parseAndValidateResponse(templateId, vAppResponse);
}
protected Map<String, String> parseAndValidateResponse(String templateId,
VApp vAppResponse) {
protected Map<String, String> parseAndValidateResponse(String templateId, VApp vAppResponse) {
Map<String, String> response = parseResponse(templateId, vAppResponse);
checkState(response.containsKey("id"),
"bad configuration: [id] should be in response");
checkState(response.containsKey("username"),
"bad configuration: [username] should be in response");
checkState(response.containsKey("password"),
"bad configuration: [password] should be in response");
checkState(response.containsKey("id"), "bad configuration: [id] should be in response");
checkState(response.containsKey("username"), "bad configuration: [username] should be in response");
checkState(response.containsKey("password"), "bad configuration: [password] should be in response");
return response;
}
protected Map<String, String> parseResponse(String templateId,
VApp vAppResponse) {
protected Map<String, String> parseResponse(String templateId, VApp vAppResponse) {
Map<String, String> config = Maps.newLinkedHashMap();// Allows nulls
config.put("id", vAppResponse.getId());
config.put("username", null);
@ -143,8 +134,7 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
private VApp undeployVAppIfDeployed(VApp vApp) {
if (vApp.getStatus().compareTo(VAppStatus.RESOLVED) > 0) {
logger.debug(">> undeploying vApp(%s), current status: %s", vApp
.getId(), vApp.getStatus());
logger.debug(">> undeploying vApp(%s), current status: %s", vApp.getId(), vApp.getStatus());
Task task = client.undeployVApp(vApp.getId());
if (!taskTester.apply(task.getId())) {
throw new TaskException("undeploy", vApp, task);
@ -157,8 +147,7 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
private VApp powerOffVAppIfDeployed(VApp vApp) {
if (vApp.getStatus().compareTo(VAppStatus.OFF) > 0) {
logger.debug(">> powering off vApp(%s), current status: %s", vApp
.getId(), vApp.getStatus());
logger.debug(">> powering off vApp(%s), current status: %s", vApp.getId(), vApp.getStatus());
Task task = client.powerOffVApp(vApp.getId());
if (!taskTester.apply(task.getId())) {
throw new TaskException("powerOff", vApp, task);
@ -176,10 +165,8 @@ public class BaseVCloudComputeClient implements VCloudComputeClient {
private static final long serialVersionUID = 251801929573211256L;
public TaskException(String type, VApp vApp, Task task) {
super(String.format(
"failed to %s vApp %s status %s;task %s status %s", type, vApp
.getId(), vApp.getStatus(), task.getLocation(), task
.getStatus()), vApp);
super(String.format("failed to %s vApp %s status %s;task %s status %s", type, vApp.getId(), vApp.getStatus(),
task.getLocation(), task.getStatus()), vApp);
this.task = task;
}

View File

@ -45,7 +45,7 @@ public class OrgAndVDCToLocationProvider implements Provider<Set<? extends Locat
@Inject
OrgAndVDCToLocationProvider(@org.jclouds.rest.annotations.Provider String providerName,
Supplier<VCloudSession> cache, VCloudClient client) {
Supplier<VCloudSession> cache, VCloudClient client) {
this.providerName = providerName;
this.cache = cache;
this.client = client;
@ -57,9 +57,9 @@ public class OrgAndVDCToLocationProvider implements Provider<Set<? extends Locat
Set<Location> locations = Sets.newLinkedHashSet();
for (NamedResource org : cache.get().getOrgs().values()) {
Location orgL = new LocationImpl(LocationScope.REGION, org.getId(), org.getName(),
provider);
for (NamedResource vdc : client.getOrganization(org.getId()).getVDCs().values()) {
Location orgL = new LocationImpl(LocationScope.REGION, org.getName(), org.getLocation().toASCIIString(),
provider);
for (NamedResource vdc : client.getOrganizationNamed(org.getName()).getVDCs().values()) {
locations.add(new LocationImpl(LocationScope.ZONE, vdc.getId(), vdc.getName(), orgL));
}
}

View File

@ -57,7 +57,9 @@ public class FindLocationForResource {
public Location apply(NamedResource resource) {
for (Location input : locations.get()) {
do {
if (input.getId().equals(resource.getId()))
if (input.getId().equals(resource.getName()))
return input;
else if (input.getId().equals(resource.getId()))
return input;
input = input.getParent();
} while (input.getParent() != null);

View File

@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
@ -77,6 +78,7 @@ import com.google.common.base.Throwables;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
/**
* Configures the VCloud authentication service connection, including logging
@ -96,6 +98,9 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
@Override
protected void configure() {
requestInjection(this);
bind(new TypeLiteral<Supplier<Map<String, NamedResource>>>() {
}).annotatedWith(Org.class).to(new TypeLiteral<OrgNameToOrgSupplier>() {
});
super.configure();
}
@ -122,14 +127,21 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
return Iterables.getLast(orgs).getLocation();
}
@Provides
@Org
@Singleton
protected String provideOrgName(@Org Iterable<NamedResource> orgs) {
return Iterables.getLast(orgs).getName();
}
@Provides
@Named("VDC_TO_ORG")
@Singleton
protected Map<String, String> provideVDCtoORG(@Org Iterable<NamedResource> orgs, VCloudClient client) {
Map<String, String> returnVal = Maps.newLinkedHashMap();
for (NamedResource orgr : orgs) {
for (NamedResource vdc : client.getOrganization(orgr.getId()).getVDCs().values()) {
returnVal.put(vdc.getId(), orgr.getId());
for (NamedResource vdc : client.getOrganizationNamed(orgr.getName()).getVDCs().values()) {
returnVal.put(vdc.getId(), orgr.getName());
}
}
return returnVal;
@ -151,14 +163,11 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
return URI.create(vcloudUri.toASCIIString().replace("/login", ""));
}
private AuthorizationException authException = null;
protected AuthorizationException authException = null;
/**
* borrowing concurrency code to ensure that caching takes place properly
*/
@Provides
@Singleton
Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final VCloudLoginAsyncClient login) {
return Suppliers.memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<VCloudSession>(
new Supplier<VCloudSession>() {
@ -200,6 +209,23 @@ public abstract class BaseVCloudRestClientModule<S extends VCloudClient, A exten
return versions.get(version);
}
@Singleton
private static class OrgNameToOrgSupplier implements Supplier<Map<String, NamedResource>> {
private final Supplier<VCloudSession> sessionSupplier;
@SuppressWarnings("unused")
@Inject
OrgNameToOrgSupplier(Supplier<VCloudSession> sessionSupplier) {
this.sessionSupplier = sessionSupplier;
}
@Override
public Map<String, NamedResource> get() {
return sessionSupplier.get().getOrgs();
}
}
@Provides
@Singleton
protected VCloudLoginAsyncClient provideVCloudLogin(AsyncClientFactory factory) {

View File

@ -32,6 +32,11 @@ import com.google.inject.ImplementedBy;
*/
@ImplementedBy(NamedResourceImpl.class)
public interface NamedResource extends Comparable<NamedResource> {
/**
* name is not a safe means to identify a resource. Please use name.
*/
@Deprecated
String getId();
String getName();

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.vcloud.functions;
import java.net.URI;
import java.util.Map;
import java.util.NoSuchElementException;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.rest.annotations.Provider;
import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.endpoints.Org;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
/**
*
* @author Adrian Cole
*/
@Singleton
public class OrgNameToEndpoint implements Function<Object, URI> {
private final Supplier<Map<String, NamedResource>> orgNameToEndpoint;
private final URI defaultUri;
@Inject
public OrgNameToEndpoint(@Org Supplier<Map<String, NamedResource>> orgNameToEndpoint, @Provider URI defaultUri) {
this.orgNameToEndpoint = orgNameToEndpoint;
this.defaultUri = defaultUri;
}
public URI apply(Object from) {
try {
return from == null ? defaultUri : orgNameToEndpoint.get().get(from).getLocation();
} catch (NullPointerException e) {
throw new NoSuchElementException("org " + from + " not found in " + orgNameToEndpoint.get().keySet());
}
}
}

View File

@ -76,7 +76,7 @@ public class OrganizatonsForLocations implements
@SuppressWarnings("unchecked")
@Override
public Future<Organization> apply(Location from) {
return (Future<Organization>) aclient.getOrganization(from.getParent().getId());
return (Future<Organization>) aclient.getOrganizationNamed(from.getParent().getId());
}
}, executor, null, logger, "organizations for locations");

View File

@ -20,6 +20,7 @@ package org.jclouds.vcloud;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount;
import static org.testng.Assert.assertEquals;
@ -27,10 +28,10 @@ import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Map;
import java.util.Properties;
import javax.inject.Named;
import javax.inject.Provider;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
@ -47,8 +48,10 @@ import org.jclouds.util.Utils;
import org.jclouds.vcloud.config.VCloudRestClientModule;
import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.domain.Organization;
import org.jclouds.vcloud.domain.internal.NamedResourceImpl;
import org.jclouds.vcloud.endpoints.Org;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient;
import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession;
import org.jclouds.vcloud.options.CloneVAppOptions;
@ -65,6 +68,8 @@ import org.jclouds.vcloud.xml.VDCHandler;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
@ -196,6 +201,21 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
checkFilters(request);
}
public void testOrganizationNamed() throws SecurityException, NoSuchMethodException, IOException {
Method method = VCloudAsyncClient.class.getMethod("getOrganizationNamed", String.class);
HttpRequest request = processor.createRequest(method, "org");
assertRequestLineEquals(request, "GET https://vcloud.safesecureweb.com/api/v0.8/org/1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.org+xml\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, OrgHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
}
public void testDefaultCatalog() throws SecurityException, NoSuchMethodException, IOException {
Method method = VCloudAsyncClient.class.getMethod("getDefaultCatalog");
HttpRequest request = processor.createRequest(method);
@ -572,17 +592,25 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
}
@Override
protected void configure() {
super.configure();
bind(SetVCloudTokenCookie.class).toInstance(new SetVCloudTokenCookie(new Provider<String>() {
protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final VCloudLoginAsyncClient login) {
return Suppliers.<VCloudSession> ofInstance(new VCloudSession() {
public String get() {
@Override
public Map<String, NamedResource> getOrgs() {
return ImmutableMap.<String, NamedResource> of("org", new NamedResourceImpl("1", "org",
VCloudMediaType.ORG_XML, URI.create("https://vcloud.safesecureweb.com/api/v0.8/org/1")));
}
@Override
public String getVCloudToken() {
return "token";
}
}));
});
}
}
}

View File

@ -57,11 +57,11 @@ public class VCloudClientLiveTest {
public void testOrganization() throws Exception {
Organization response = connection.getDefaultOrganization();
assertNotNull(response);
assertNotNull(response.getId());
assertNotNull(response.getName());
assert response.getCatalogs().size() >= 1;
assert response.getTasksLists().size() >= 1;
assert response.getVDCs().size() >= 1;
assertEquals(connection.getOrganization(response.getId()), response);
assertEquals(connection.getOrganizationNamed(response.getName()), response);
}
@Test
@ -161,15 +161,14 @@ public class VCloudClientLiveTest {
@BeforeGroups(groups = { "live" })
public void setupClient() {
String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"),
"jclouds.test.endpoint");
String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"), "jclouds.test.endpoint");
identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential");
Properties props = new Properties();
props.setProperty("vcloud.endpoint", endpoint);
context = new RestContextFactory().createContext("vcloud", identity, credential, ImmutableSet
.<Module> of(new Log4JLoggingModule()), props);
.<Module> of(new Log4JLoggingModule()), props);
connection = context.getApi();
}

View File

@ -20,6 +20,7 @@ package org.jclouds.vcloud.terremark;
import static org.jclouds.vcloud.VCloudMediaType.CATALOG_XML;
import static org.jclouds.vcloud.VCloudMediaType.ORG_XML;
import static org.jclouds.vcloud.VCloudMediaType.TASK_XML;
import static org.jclouds.vcloud.VCloudMediaType.VAPP_XML;
import static org.jclouds.vcloud.VCloudMediaType.VDC_XML;
import static org.jclouds.vcloud.terremark.TerremarkVCloudMediaType.CATALOGITEMCUSTOMIZATIONPARAMETERS_XML;
@ -31,6 +32,7 @@ import static org.jclouds.vcloud.terremark.TerremarkVCloudMediaType.PUBLICIP_XML
import java.util.Set;
import javax.annotation.Nullable;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
@ -43,6 +45,7 @@ import javax.ws.rs.Produces;
import org.jclouds.predicates.validators.DnsNameValidator;
import org.jclouds.rest.annotations.BinderParam;
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.MapPayloadParam;
@ -55,13 +58,14 @@ import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.vcloud.VCloudAsyncClient;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.VDC;
import org.jclouds.vcloud.endpoints.Org;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.functions.CatalogIdToUri;
import org.jclouds.vcloud.functions.OrgNameToEndpoint;
import org.jclouds.vcloud.functions.VAppId;
import org.jclouds.vcloud.functions.VAppTemplateIdToUri;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
@ -89,6 +93,7 @@ import org.jclouds.vcloud.terremark.xml.PublicIpAddressesHandler;
import org.jclouds.vcloud.terremark.xml.TerremarkOrgHandler;
import org.jclouds.vcloud.terremark.xml.TerremarkVDCHandler;
import org.jclouds.vcloud.xml.CatalogHandler;
import org.jclouds.vcloud.xml.TaskHandler;
import org.jclouds.vcloud.xml.VAppHandler;
import com.google.common.util.concurrent.ListenableFuture;
@ -97,7 +102,8 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides access to VCloud resources via their REST API.
* <p/>
*
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx" />
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx"
* />
* @author Adrian Cole
*/
@RequestFilters(SetVCloudTokenCookie.class)
@ -117,6 +123,16 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@Consumes(ORG_XML)
ListenableFuture<? extends TerremarkOrganization> getOrganization(@PathParam("orgId") String orgId);
/**
* @see VCloudClient#getOrganizationNamed
*/
@GET
@XMLResponseParser(TerremarkOrgHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Consumes(ORG_XML)
ListenableFuture<? extends TerremarkOrganization> getOrganizationNamed(
@Nullable @EndpointParam(parser = OrgNameToEndpoint.class) String orgName);
/**
* @see TerremarkVCloudExpressClient#getDefaultVDC
*/
@ -158,9 +174,9 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(VAppHandler.class)
@MapBinder(TerremarkBindInstantiateVAppTemplateParamsToXmlPayload.class)
ListenableFuture<? extends VApp> instantiateVAppTemplateInVDC(@PathParam("vDCId") String vDCId,
@MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName,
@MapPayloadParam("template") @ParamParser(VAppTemplateIdToUri.class) String templateId,
InstantiateVAppTemplateOptions... options);
@MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName,
@MapPayloadParam("template") @ParamParser(VAppTemplateIdToUri.class) String templateId,
InstantiateVAppTemplateOptions... options);
/**
* @see TerremarkVCloudExpressClient#addInternetService
@ -173,8 +189,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(InternetServiceHandler.class)
@MapBinder(AddInternetServiceOptions.class)
ListenableFuture<? extends InternetService> addInternetServiceToVDC(@PathParam("vDCId") String vDCId,
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options);
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options);
/**
* @see TerremarkVCloudExpressClient#getAllInternetServices
@ -198,8 +214,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(InternetServiceHandler.class)
@MapBinder(AddInternetServiceOptions.class)
ListenableFuture<? extends InternetService> addInternetServiceToExistingIp(@PathParam("ipId") int existingIpId,
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options);
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options);
/**
* @see TerremarkVCloudExpressClient#deletePublicIp
@ -284,8 +300,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(NodeHandler.class)
@MapBinder(AddNodeOptions.class)
ListenableFuture<? extends Node> addNode(@PathParam("internetServiceId") int internetServiceId,
@MapPayloadParam("ipAddress") String ipAddress, @MapPayloadParam("name") String name,
@MapPayloadParam("port") int port, AddNodeOptions... options);
@MapPayloadParam("ipAddress") String ipAddress, @MapPayloadParam("name") String name,
@MapPayloadParam("port") int port, AddNodeOptions... options);
/**
* @see TerremarkVCloudExpressClient#getNodes
@ -319,7 +335,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@Consumes(NODESERVICE_XML)
@XMLResponseParser(NodeHandler.class)
ListenableFuture<? extends Node> configureNode(@PathParam("nodeId") int nodeId,
@BinderParam(BindNodeConfigurationToXmlPayload.class) NodeConfiguration nodeConfiguration);
@BinderParam(BindNodeConfigurationToXmlPayload.class) NodeConfiguration nodeConfiguration);
/**
* @see TerremarkVCloudExpressClient#deleteNode
@ -341,7 +357,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@MapBinder(BindVAppConfigurationToXmlPayload.class)
@ResponseParser(ParseTaskFromLocationHeader.class)
ListenableFuture<? extends Task> configureVApp(@PathParam("vAppId") @ParamParser(VAppId.class) VApp vApp,
VAppConfiguration configuration);
VAppConfiguration configuration);
/**
* @see TerremarkVCloudExpressClient#getCustomizationOptionsOfCatalogItem
@ -352,6 +368,6 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(CustomizationParametersHandler.class)
@Consumes(CATALOGITEMCUSTOMIZATIONPARAMETERS_XML)
ListenableFuture<? extends CustomizationParameters> getCustomizationOptionsOfCatalogItem(
@PathParam("catalogItemId") String catalogItemId);
@PathParam("catalogItemId") String catalogItemId);
}

View File

@ -40,16 +40,21 @@ import org.jclouds.vcloud.terremark.options.AddNodeOptions;
* Provides access to VCloud resources via their REST API.
* <p/>
*
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx" />
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx"
* />
* @author Adrian Cole
*/
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface TerremarkVCloudClient extends VCloudClient {
@Override
TerremarkOrganization getDefaultOrganization();
@Override
TerremarkOrganization getOrganization(String orgId);
@Override
TerremarkOrganization getOrganizationNamed(String orgName);
CustomizationParameters getCustomizationOptionsOfCatalogItem(String catalogItemId);
/**
@ -68,20 +73,21 @@ public interface TerremarkVCloudClient extends VCloudClient {
PublicIpAddress activatePublicIpInVDC(String vDCId);
/**
* The call creates a new internet server, including protocol and port information. The public IP
* is dynamically allocated.
* The call creates a new internet server, including protocol and port
* information. The public IP is dynamically allocated.
*
*/
InternetService addInternetServiceToVDC(String vDCId, String serviceName, Protocol protocol,
int port, AddInternetServiceOptions... options);
InternetService addInternetServiceToVDC(String vDCId, String serviceName, Protocol protocol, int port,
AddInternetServiceOptions... options);
/**
* This call adds an internet service to a known, existing public IP. This call is identical to
* Add Internet Service except you specify the public IP in the request.
* This call adds an internet service to a known, existing public IP. This
* call is identical to Add Internet Service except you specify the public IP
* in the request.
*
*/
InternetService addInternetServiceToExistingIp(int existingIpId, String serviceName,
Protocol protocol, int port, AddInternetServiceOptions... options);
InternetService addInternetServiceToExistingIp(int existingIpId, String serviceName, Protocol protocol, int port,
AddInternetServiceOptions... options);
void deleteInternetService(int internetServiceId);
@ -99,9 +105,10 @@ public interface TerremarkVCloudClient extends VCloudClient {
/**
* This call adds a node to an existing internet service.
* <p/>
* Every vDC is assigned a network of 60 IP addresses that can be used as nodes. Each node can
* associated with multiple internet service. You can get a list of the available IP addresses by
* calling Get IP Addresses for a Network.
* Every vDC is assigned a network of 60 IP addresses that can be used as
* nodes. Each node can associated with multiple internet service. You can
* get a list of the available IP addresses by calling Get IP Addresses for a
* Network.
*
* @param internetServiceId
* @param ipAddress
@ -110,8 +117,7 @@ public interface TerremarkVCloudClient extends VCloudClient {
* @param options
* @return
*/
Node addNode(int internetServiceId, String ipAddress, String name, int port,
AddNodeOptions... options);
Node addNode(int internetServiceId, String ipAddress, String name, int port, AddNodeOptions... options);
Node getNode(int nodeId);
@ -122,8 +128,9 @@ public interface TerremarkVCloudClient extends VCloudClient {
Set<Node> getNodes(int internetServiceId);
/**
* This call configures the settings of an existing vApp by passing the new configuration. The
* existing vApp must be in a powered off state (status = 2).
* This call configures the settings of an existing vApp by passing the new
* configuration. The existing vApp must be in a powered off state (status =
* 2).
* <p/>
* You can change the following items for a vApp.
* <ol>
@ -132,8 +139,9 @@ public interface TerremarkVCloudClient extends VCloudClient {
* <li>Add a virtual disk</li>
* <li>Delete a virtual disk</li>
* </ol>
* You can make more than one change in a single request. For example, you can increase the
* number of virtual CPUs and the amount of virtual memory in the same request.
* You can make more than one change in a single request. For example, you
* can increase the number of virtual CPUs and the amount of virtual memory
* in the same request.
*
* @param vApp
* vApp to change in power state off

View File

@ -21,17 +21,17 @@ package org.jclouds.vcloud.terremark;
import static javax.ws.rs.core.MediaType.APPLICATION_XML;
import static org.jclouds.vcloud.terremark.TerremarkVCloudExpressMediaType.KEYSLIST_XML;
import java.net.URI;
import java.util.Set;
import javax.annotation.Nullable;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
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.MapPayloadParam;
@ -43,7 +43,8 @@ import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.terremark.binders.BindCreateKeyToXmlPayload;
import org.jclouds.vcloud.terremark.domain.KeyPair;
import org.jclouds.vcloud.terremark.endpoints.KeysList;
import org.jclouds.vcloud.terremark.functions.OrgNameToKeysListEndpoint;
import org.jclouds.vcloud.terremark.xml.KeyPairByNameHandler;
import org.jclouds.vcloud.terremark.xml.KeyPairHandler;
import org.jclouds.vcloud.terremark.xml.KeyPairsHandler;
@ -53,56 +54,53 @@ import com.google.common.util.concurrent.ListenableFuture;
* Provides access to VCloud resources via their REST API.
* <p/>
*
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx" />
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx"
* />
* @author Adrian Cole
*/
@RequestFilters(SetVCloudTokenCookie.class)
public interface TerremarkVCloudExpressAsyncClient extends TerremarkVCloudAsyncClient {
/**
* @see TerremarkVCloudExpressClient#listKeyPairs
*/
@GET
@Endpoint(KeysList.class)
@Consumes(KEYSLIST_XML)
@XMLResponseParser(KeyPairsHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<KeyPair>> listKeyPairs();
/**
* @see TerremarkVCloudExpressClient#listKeyPairsInOrg
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/extensions/org/{orgId}/keys")
@Consumes(KEYSLIST_XML)
@XMLResponseParser(KeyPairsHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<KeyPair>> listKeyPairsInOrg(@PathParam("orgId") String orgId);
ListenableFuture<? extends Set<KeyPair>> listKeyPairsInOrg(
@Nullable @EndpointParam(parser = OrgNameToKeysListEndpoint.class) String orgName);
/**
* @see TerremarkVCloudExpressClient#generateKeyPairInOrg
*/
@POST
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/extensions/org/{orgId}/keys")
@Produces(KEYSLIST_XML)
@Consumes(KEYSLIST_XML)
@XMLResponseParser(KeyPairHandler.class)
@MapBinder(BindCreateKeyToXmlPayload.class)
ListenableFuture<? extends KeyPair> generateKeyPairInOrg(@PathParam("orgId") String orgId,
@MapPayloadParam("name") String name, @MapPayloadParam("isDefault") boolean makeDefault);
ListenableFuture<? extends KeyPair> generateKeyPairInOrg(
@Nullable @EndpointParam(parser = OrgNameToKeysListEndpoint.class) String orgName,
@MapPayloadParam("name") String name, @MapPayloadParam("isDefault") boolean makeDefault);
/**
* @see TerremarkVCloudExpressClient#getKeyPair
*/
@GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/extensions/key/{keyId}")
@XMLResponseParser(KeyPairHandler.class)
@Consumes(APPLICATION_XML)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends KeyPair> getKeyPair(@PathParam("keyId") int keyId);
ListenableFuture<? extends KeyPair> getKeyPair(@EndpointParam URI keyId);
/**
* @see TerremarkVCloudExpressClient#getKeyPairInOrg
*/
@GET
@XMLResponseParser(KeyPairByNameHandler.class)
@Consumes(KEYSLIST_XML)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends KeyPair> getKeyPairInOrg(
@Nullable @EndpointParam(parser = OrgNameToKeysListEndpoint.class) String orgName, String keyName);
// TODO
// /**
@ -123,9 +121,7 @@ public interface TerremarkVCloudExpressAsyncClient extends TerremarkVCloudAsyncC
* @see TerremarkVCloudExpressClient#deleteKeyPair
*/
@DELETE
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/extensions/key/{keyId}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> deleteKeyPair(@PathParam("keyId") int keyId);
ListenableFuture<Void> deleteKeyPair(@EndpointParam URI keyId);
}

View File

@ -18,36 +18,56 @@
*/
package org.jclouds.vcloud.terremark;
import java.net.URI;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.vcloud.terremark.domain.KeyPair;
/**
* Provides access to VCloud resources via their REST API.
* <p/>
*
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx" />
* @see <a href="https://community.vcloudexpress.terremark.com/en-us/discussion_forums/f/60.aspx"
* />
* @author Adrian Cole
*/
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface TerremarkVCloudExpressClient extends TerremarkVCloudClient {
/**
* This call returns the keys previously created for your organization.
* @param orgName
* null if use the default org
* @throws ResourceNotFoundException
* if the orgName is not a valid organization
*/
Set<KeyPair> listKeyPairs();
Set<KeyPair> listKeyPairsInOrg(@Nullable String orgName);
Set<KeyPair> listKeyPairsInOrg(String orgId);
/**
* @param orgName
* null if use the default org
* @throws ResourceNotFoundException
* if the orgName is not a valid organization
*/
KeyPair generateKeyPairInOrg(@Nullable String orgName, String name, boolean makeDefault);
KeyPair generateKeyPairInOrg(String orgId, String name, boolean makeDefault);
/**
* @param orgName
* null if use the default org
* @throws ResourceNotFoundException
* if the orgName is not a valid organization
*/
KeyPair getKeyPairInOrg(@Nullable String orgName, String keyPairName);
KeyPair getKeyPair(int keyPairId);
KeyPair getKeyPair(URI keyPair);
// TODO
// KeyPair configureKeyPair(int keyPairId, KeyPairConfiguration
// keyPairConfiguration);
void deleteKeyPair(int keyPairId);
void deleteKeyPair(URI keyPair);
}

View File

@ -103,8 +103,8 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
@Inject
protected TerremarkVCloudAddNodeWithTagStrategy(TerremarkVCloudClient client,
TerremarkVCloudComputeClient computeClient, GetNodeMetadataStrategy getNode,
TemplateToInstantiateOptions getOptions) {
TerremarkVCloudComputeClient computeClient, GetNodeMetadataStrategy getNode,
TemplateToInstantiateOptions getOptions) {
this.client = client;
this.computeClient = computeClient;
this.getNode = getNode;
@ -114,9 +114,8 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
@Override
public NodeMetadata execute(String tag, String name, Template template) {
TerremarkInstantiateVAppTemplateOptions options = getOptions.apply(template);
Map<String, String> metaMap = computeClient.start(template.getLocation().getId(), name,
template.getImage().getProviderId(), options, template.getOptions()
.getInboundPorts());
Map<String, String> metaMap = computeClient.start(template.getLocation().getId(), name, template.getImage()
.getProviderId(), options, template.getOptions().getInboundPorts());
return getNode.execute(metaMap.get("id"));
}
@ -124,17 +123,15 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
@Singleton
public static class TemplateToInstantiateOptions implements
Function<Template, TerremarkInstantiateVAppTemplateOptions> {
Function<Template, TerremarkInstantiateVAppTemplateOptions> {
@Override
public TerremarkInstantiateVAppTemplateOptions apply(Template from) {
TerremarkInstantiateVAppTemplateOptions options = processorCount(
Double.valueOf(from.getSize().getCores()).intValue()).memory(
from.getSize().getRam());
Double.valueOf(from.getSize().getCores()).intValue()).memory(from.getSize().getRam());
if (!from.getOptions().shouldBlockUntilRunning())
options.blockOnDeploy(false);
String sshKeyFingerprint = TerremarkVCloudTemplateOptions.class.cast(from.getOptions())
.getSshKeyFingerprint();
String sshKeyFingerprint = TerremarkVCloudTemplateOptions.class.cast(from.getOptions()).getSshKeyFingerprint();
if (sshKeyFingerprint != null)
options.sshKeyFingerprint(sshKeyFingerprint);
@ -151,8 +148,7 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
}).to(new TypeLiteral<ComputeServiceContextImpl<VCloudClient, VCloudAsyncClient>>() {
}).in(Scopes.SINGLETON);
// NOTE
bind(RunNodesAndAddToSetStrategy.class).to(
TerremarkEncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy.class);
bind(RunNodesAndAddToSetStrategy.class).to(TerremarkEncodeTemplateIdIntoNameRunNodesAndAddToSetStrategy.class);
bind(ListNodesStrategy.class).to(VCloudListNodesStrategy.class);
// NOTE
bind(GetNodeMetadataStrategy.class).to(TerremarkVCloudGetNodeMetadataStrategy.class);
@ -170,7 +166,7 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
bind(ComputeService.class).to(TerremarkVCloudComputeService.class);
bind(VCloudComputeClient.class).to(TerremarkVCloudComputeClient.class);
bind(PopulateDefaultLoginCredentialsForImageStrategy.class).to(
ParseVAppTemplateDescriptionToGetDefaultLoginCredentials.class);
ParseVAppTemplateDescriptionToGetDefaultLoginCredentials.class);
bind(SecureRandom.class).toInstance(new SecureRandom());
}
@ -203,8 +199,7 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
@Override
protected void bindImages() {
bind(new TypeLiteral<Set<? extends Image>>() {
}).toProvider(VAppTemplatesInOrgs.class).in(
Scopes.SINGLETON);
}).toProvider(VAppTemplatesInOrgs.class).in(Scopes.SINGLETON);
}
}

View File

@ -46,18 +46,16 @@ public class DeleteKeyPair {
final ConcurrentMap<OrgAndName, KeyPair> credentialsMap;
@Inject
DeleteKeyPair(TerremarkVCloudExpressClient terremarkClient,
ConcurrentMap<OrgAndName, KeyPair> credentialsMap) {
DeleteKeyPair(TerremarkVCloudExpressClient terremarkClient, ConcurrentMap<OrgAndName, KeyPair> credentialsMap) {
this.terremarkClient = terremarkClient;
this.credentialsMap = credentialsMap;
}
public void execute(OrgAndName orgTag) {
for (KeyPair keyPair : terremarkClient.listKeyPairsInOrg(orgTag.getOrg())) {
if (keyPair.getName().matches(
"jclouds#" + orgTag.getName() + "-[0-9]+")) {
if (keyPair.getName().matches("jclouds#" + orgTag.getName() + "-[0-9]+")) {
logger.debug(">> deleting keyPair(%s)", keyPair.getName());
terremarkClient.deleteKeyPair(keyPair.getId());
terremarkClient.deleteKeyPair(keyPair.getLocation());
// TODO: test this clear happens
credentialsMap.remove(orgTag);
logger.debug("<< deleted keyPair(%s)", keyPair.getName());

View File

@ -18,36 +18,48 @@
*/
package org.jclouds.vcloud.terremark.config;
import java.io.IOException;
import java.net.URI;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.concurrent.RetryOnTimeOutExceptionSupplier;
import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.util.Utils;
import org.jclouds.vcloud.VCloudAsyncClient;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.Organization;
import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession;
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudExpressAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudExpressClient;
import org.jclouds.vcloud.terremark.domain.TerremarkOrganization;
import org.jclouds.vcloud.terremark.endpoints.KeysList;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.google.inject.Provides;
/**
* Configures the VCloud authentication service connection, including logging and http transport.
* Configures the VCloud authentication service connection, including logging
* and http transport.
*
* @author Adrian Cole
*/
@RequiresHttp
@ConfiguresRestClient
public class TerremarkVCloudExpressRestClientModule extends
TerremarkRestClientModule<TerremarkVCloudExpressClient, TerremarkVCloudExpressAsyncClient> {
TerremarkRestClientModule<TerremarkVCloudExpressClient, TerremarkVCloudExpressAsyncClient> {
public TerremarkVCloudExpressRestClientModule() {
super(TerremarkVCloudExpressClient.class, TerremarkVCloudExpressAsyncClient.class);
@ -77,11 +89,63 @@ public class TerremarkVCloudExpressRestClientModule extends
return in;
}
@Provides
@KeysList
@Singleton
protected URI provideDefaultKeysList(Organization org) {
return TerremarkOrganization.class.cast(org).getKeysList().getLocation();
public static class OrgNameToKeysListSupplier implements Supplier<Map<String, NamedResource>> {
protected final Supplier<VCloudSession> sessionSupplier;
private final TerremarkVCloudExpressClient client;
@Inject
protected OrgNameToKeysListSupplier(Supplier<VCloudSession> sessionSupplier, TerremarkVCloudExpressClient client) {
this.sessionSupplier = sessionSupplier;
this.client = client;
}
@Override
public Map<String, NamedResource> get() {
return Maps.transformValues(sessionSupplier.get().getOrgs(), new Function<NamedResource, NamedResource>() {
@Override
public NamedResource apply(NamedResource from) {
return client.getOrganizationNamed(from.getName()).getKeysList();
}
});
}
}
@Provides
@Singleton
@KeysList
protected Supplier<Map<String, NamedResource>> provideOrgToKeysListCache(
@Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgNameToKeysListSupplier supplier) {
return Suppliers.memoizeWithExpiration(new RetryOnTimeOutExceptionSupplier<Map<String, NamedResource>>(
new Supplier<Map<String, NamedResource>>() {
public Map<String, NamedResource> get() {
// http://code.google.com/p/google-guice/issues/detail?id=483
// guice doesn't remember when singleton providers throw
// exceptions.
// in this case, if describeRegions fails, it is called
// again for
// each provider method that depends on it. To
// short-circuit this,
// we remember the last exception trusting that guice is
// single-threaded
if (TerremarkVCloudExpressRestClientModule.this.authException != null)
throw TerremarkVCloudExpressRestClientModule.this.authException;
try {
return supplier.get();
} catch (AuthorizationException e) {
TerremarkVCloudExpressRestClientModule.this.authException = e;
throw e;
} catch (Exception e) {
Throwables.propagate(e);
assert false : e;
return null;
}
}
}), seconds, TimeUnit.SECONDS);
}
@Singleton

View File

@ -0,0 +1,41 @@
package org.jclouds.vcloud.terremark.functions;
import java.net.URI;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.endpoints.Org;
import org.jclouds.vcloud.terremark.endpoints.KeysList;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
/**
*
* @author Adrian Cole
*/
@Singleton
public class OrgNameToKeysListEndpoint implements Function<Object, URI> {
private final Supplier<Map<String, NamedResource>> orgNameToEndpoint;
private final String defaultOrg;
@Inject
public OrgNameToKeysListEndpoint(@KeysList Supplier<Map<String, NamedResource>> orgNameToEndpoint,
@Org String defaultUri) {
this.orgNameToEndpoint = orgNameToEndpoint;
this.defaultOrg = defaultUri;
}
public URI apply(Object from) {
try {
return orgNameToEndpoint.get().get(from == null ? defaultOrg : from).getLocation();
} catch (NullPointerException e) {
throw new ResourceNotFoundException("org " + from + " not found in " + orgNameToEndpoint.get().keySet());
}
}
}

View File

@ -36,29 +36,32 @@ public class ParseTerremarkVCloudErrorFromHttpResponse implements HttpErrorHandl
try {
String content = parseErrorFromContentOrNull(command, response);
switch (response.getStatusCode()) {
case 401:
exception = new AuthorizationException(command.getRequest(), content);
break;
case 403: // TODO temporary as terremark mistakenly uses this for vApp not found.
case 404:
if (!command.getRequest().getMethod().equals("DELETE")) {
String path = command.getRequest().getEndpoint().getPath();
Matcher matcher = RESOURCE_PATTERN.matcher(path);
String message;
if (matcher.find()) {
message = String.format("%s %s not found", matcher.group(1), matcher.group(2));
} else {
message = path;
}
exception = new ResourceNotFoundException(message);
case 401:
exception = new AuthorizationException(command.getRequest(), content);
break;
case 403: // TODO temporary as terremark mistakenly uses this for vApp
// not found.
case 404:
if (!command.getRequest().getMethod().equals("DELETE")) {
String path = command.getRequest().getEndpoint().getPath();
Matcher matcher = RESOURCE_PATTERN.matcher(path);
String message;
if (matcher.find()) {
message = String.format("%s %s not found", matcher.group(1), matcher.group(2));
} else {
message = path;
}
break;
case 500:
if (response.getMessage().indexOf("because there is a pending task running") != -1)
exception = new IllegalStateException(response.getMessage(), exception);
break;
default:
exception = new HttpResponseException(command, response, content);
exception = new ResourceNotFoundException(message);
}
break;
case 500:
if (response.getMessage().indexOf("because there is a pending task running") != -1)
exception = new IllegalStateException(response.getMessage(), exception);
else if (response.getMessage().indexOf("because it is already powered off") != -1)
exception = new IllegalStateException(response.getMessage(), exception);
break;
default:
exception = new HttpResponseException(command, response, content);
}
} finally {
releasePayload(response);

View File

@ -0,0 +1,80 @@
/**
*
* 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.terremark.xml;
import java.util.NoSuchElementException;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.terremark.domain.KeyPair;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
/**
* @author Adrian Cole
*/
public class KeyPairByNameHandler extends ParseSax.HandlerForGeneratedRequestWithResult<KeyPair> {
@Resource
protected Logger logger = Logger.NULL;
private final KeyPairsHandler handler;
@Inject
public KeyPairByNameHandler(KeyPairsHandler handler) {
this.handler = handler;
}
@Override
public KeyPair getResult() {
final String name = getRequest().getArgs()[1].toString();
try {
return Iterables.find(handler.getResult(), new Predicate<KeyPair>() {
@Override
public boolean apply(KeyPair input) {
return input.getName().equals(name);
}
});
} catch (NoSuchElementException e) {
logger.debug("keypair %s/%s not found in %s", getRequest().getArgs()[0], name, handler.getResult());
return null;
}
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
handler.startElement(uri, localName, qName, attributes);
}
public void endElement(String uri, String name, String qName) {
handler.endElement(uri, name, qName);
}
public void characters(char ch[], int start, int length) {
handler.characters(ch, start, length);
}
}

View File

@ -36,13 +36,12 @@ public class TerremarkOrgHandler extends OrgHandler {
private NamedResource keysList;
public TerremarkOrganization getResult() {
return new TerremarkOrganizationImpl(org.getId(), org.getName(), org.getLocation(), catalogs,
vdcs, tasksLists, keysList);
return new TerremarkOrganizationImpl(org.getId(), org.getName(), org.getLocation(), catalogs, vdcs, tasksLists,
keysList);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if (qName.equals("Link")) {
int typeIndex = attributes.getIndex("type");

View File

@ -48,10 +48,10 @@ public class TerremarkVCloudClientLiveTest extends TerremarkClientLiveTest {
public void testKeysList() throws Exception {
TerremarkVCloudExpressClient vCloudExpressClient = TerremarkVCloudExpressClient.class.cast(tmClient);
TerremarkOrganization org = vCloudExpressClient.getDefaultOrganization();
Set<KeyPair> response = vCloudExpressClient.listKeyPairs();
Set<KeyPair> response = vCloudExpressClient.listKeyPairsInOrg(null);
assertNotNull(response);
System.err.println(response);
assertEquals(response, vCloudExpressClient.listKeyPairsInOrg(org.getId()));
assertEquals(response, vCloudExpressClient.listKeyPairsInOrg(org.getName()));
}
@Override
@ -59,21 +59,22 @@ public class TerremarkVCloudClientLiveTest extends TerremarkClientLiveTest {
TerremarkVCloudExpressClient vCloudExpressClient = TerremarkVCloudExpressClient.class.cast(tmClient);
TerremarkOrganization org = vCloudExpressClient.getDefaultOrganization();
key = vCloudExpressClient.generateKeyPairInOrg(org.getId(), "livetest", false);
key = vCloudExpressClient.generateKeyPairInOrg(org.getName(), "livetest", false);
assertNotNull(key);
System.err.println(key);
assertEquals(key.getName(), "livetest");
assertNotNull(key.getPrivateKey());
assertNotNull(key.getFingerPrint());
assertEquals(key.isDefault(), false);
assertEquals(key.getFingerPrint(), vCloudExpressClient.getKeyPair(key.getId()).getFingerPrint());
assertEquals(key.getFingerPrint(), vCloudExpressClient.getKeyPairInOrg(org.getName(), key.getName())
.getFingerPrint());
}
@AfterTest
void cleanup1() throws InterruptedException, ExecutionException, TimeoutException {
if (key != null) {
TerremarkVCloudExpressClient vCloudExpressClient = TerremarkVCloudExpressClient.class.cast(tmClient);
vCloudExpressClient.deleteKeyPair(key.getId());
vCloudExpressClient.deleteKeyPair(key.getLocation());
}
}

View File

@ -20,6 +20,7 @@ package org.jclouds.vcloud.terremark;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import static org.jclouds.vcloud.terremark.options.AddInternetServiceOptions.Builder.disabled;
import static org.testng.Assert.assertEquals;
@ -27,15 +28,19 @@ import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Map;
import java.util.Properties;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextFactory.ContextSpec;
@ -45,10 +50,13 @@ import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Utils;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.domain.Organization;
import org.jclouds.vcloud.domain.internal.NamedResourceImpl;
import org.jclouds.vcloud.endpoints.Org;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient;
import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
@ -61,6 +69,8 @@ import org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOpti
import org.jclouds.vcloud.terremark.xml.CustomizationParametersHandler;
import org.jclouds.vcloud.terremark.xml.InternetServiceHandler;
import org.jclouds.vcloud.terremark.xml.InternetServicesHandler;
import org.jclouds.vcloud.terremark.xml.KeyPairByNameHandler;
import org.jclouds.vcloud.terremark.xml.KeyPairHandler;
import org.jclouds.vcloud.terremark.xml.KeyPairsHandler;
import org.jclouds.vcloud.terremark.xml.NodeHandler;
import org.jclouds.vcloud.terremark.xml.NodesHandler;
@ -70,17 +80,21 @@ import org.jclouds.vcloud.xml.CatalogHandler;
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.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code TerremarkVCloudAsyncClient}
* Tests behavior of {@code TerremarkVCloudExpressAsyncClient}
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true, testName = "vcloud.TerremarkVCloudAsyncClientTest")
public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVCloudExpressAsyncClient> {
@Test(groups = "unit", sequential = true, testName = "TerremarkVCloudExpressAsyncClientTest")
public class TerremarkVCloudExpressAsyncClientTest extends RestClientTest<TerremarkVCloudExpressAsyncClient> {
/**
* ignore parameter of catalog id since this doesn't work
*/
@ -131,14 +145,14 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testInstantiateVAppTemplate() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", String.class,
String.class, String.class, Array.newInstance(InstantiateVAppTemplateOptions.class, 0).getClass());
String.class, String.class, Array.newInstance(InstantiateVAppTemplateOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, "1", "name", 3 + "");
assertRequestLineEquals(request, "POST https://vcloud/vdc/1/action/instantiateVAppTemplate HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/InstantiateVAppTemplateParams-test.xml")),
"application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false);
"/terremark/InstantiateVAppTemplateParams-test.xml")),
"application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VAppHandler.class);
@ -149,16 +163,16 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testInstantiateVAppTemplateOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", String.class,
String.class, String.class, Array.newInstance(InstantiateVAppTemplateOptions.class, 0).getClass());
String.class, String.class, Array.newInstance(InstantiateVAppTemplateOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, "1", "name", 3 + "",
TerremarkInstantiateVAppTemplateOptions.Builder.processorCount(2).memory(512).inRow("row").inGroup(
"group").withPassword("password").inNetwork(URI.create("http://network")));
TerremarkInstantiateVAppTemplateOptions.Builder.processorCount(2).memory(512).inRow("row").inGroup("group")
.withPassword("password").inNetwork(URI.create("http://network")));
assertRequestLineEquals(request, "POST https://vcloud/vdc/1/action/instantiateVAppTemplate HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/InstantiateVAppTemplateParams-options-test.xml")),
"application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false);
"/terremark/InstantiateVAppTemplateParams-options-test.xml")),
"application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VAppHandler.class);
@ -184,14 +198,13 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddInternetService() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToVDC", String.class,
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0)
.getClass());
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, "1", "name", Protocol.TCP, 22);
assertRequestLineEquals(request, "POST https://vcloud/extensions/vdc/1/internetServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/CreateInternetService-test2.xml")), "application/vnd.tmrk.vCloud.internetService+xml", false);
"/terremark/CreateInternetService-test2.xml")), "application/vnd.tmrk.vCloud.internetService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InternetServiceHandler.class);
@ -202,16 +215,15 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddInternetServiceOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToVDC", String.class,
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0)
.getClass());
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, "1", "name", Protocol.TCP, 22, disabled().withDescription(
"yahoo"));
"yahoo"));
assertRequestLineEquals(request, "POST https://vcloud/extensions/vdc/1/internetServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/CreateInternetService-options-test.xml")),
"application/vnd.tmrk.vCloud.internetService+xml", false);
"/terremark/CreateInternetService-options-test.xml")), "application/vnd.tmrk.vCloud.internetService+xml",
false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InternetServiceHandler.class);
assertExceptionParserClassEquals(method, null);
@ -266,14 +278,13 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddInternetServiceToExistingIp() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToExistingIp", int.class,
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0)
.getClass());
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, 12, "name", Protocol.TCP, 22);
assertRequestLineEquals(request, "POST https://vcloud/extensions/publicIp/12/internetServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/CreateInternetService-test2.xml")), "application/vnd.tmrk.vCloud.internetService+xml", false);
"/terremark/CreateInternetService-test2.xml")), "application/vnd.tmrk.vCloud.internetService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InternetServiceHandler.class);
@ -284,16 +295,15 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddInternetServiceToExistingIpOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToExistingIp", int.class,
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0)
.getClass());
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, 12, "name", Protocol.TCP, 22, disabled().withDescription(
"yahoo"));
"yahoo"));
assertRequestLineEquals(request, "POST https://vcloud/extensions/publicIp/12/internetServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/CreateInternetService-options-test.xml")),
"application/vnd.tmrk.vCloud.internetService+xml", false);
"/terremark/CreateInternetService-options-test.xml")), "application/vnd.tmrk.vCloud.internetService+xml",
false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InternetServiceHandler.class);
assertExceptionParserClassEquals(method, null);
@ -303,13 +313,13 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddNode() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addNode", int.class, String.class,
String.class, int.class, Array.newInstance(AddNodeOptions.class, 0).getClass());
String.class, int.class, Array.newInstance(AddNodeOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, 12, "10.2.2.2", "name", 22);
assertRequestLineEquals(request, "POST https://vcloud/extensions/internetService/12/nodeServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/CreateNodeService-test2.xml")), "application/vnd.tmrk.vCloud.nodeService+xml", false);
"/terremark/CreateNodeService-test2.xml")), "application/vnd.tmrk.vCloud.nodeService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class);
@ -320,15 +330,15 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddNodeOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addNode", int.class, String.class,
String.class, int.class, Array.newInstance(AddNodeOptions.class, 0).getClass());
String.class, int.class, Array.newInstance(AddNodeOptions.class, 0).getClass());
HttpRequest request = processor.createRequest(method, 12, "10.2.2.2", "name", 22, AddNodeOptions.Builder
.disabled().withDescription("yahoo"));
.disabled().withDescription("yahoo"));
assertRequestLineEquals(request, "POST https://vcloud/extensions/internetService/12/nodeServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/CreateNodeService-options-test.xml")), "application/vnd.tmrk.vCloud.nodeService+xml", false);
"/terremark/CreateNodeService-options-test.xml")), "application/vnd.tmrk.vCloud.nodeService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class);
assertExceptionParserClassEquals(method, null);
@ -336,16 +346,16 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
checkFilters(request);
}
public void testGetKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getNode", int.class);
HttpRequest request = processor.createRequest(method, 12);
public void testGetKeyPairInOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getKeyPairInOrg", String.class, String.class);
HttpRequest request = processor.createRequest(method, "org", "keyPair");
assertRequestLineEquals(request, "GET https://vcloud/extensions/nodeService/12 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertRequestLineEquals(request, "GET https://vcloud.safesecureweb.com/api/v0.8/org/1/keysList HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vcloudExpress.keysList+xml\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class);
assertSaxResponseParserClassEquals(method, KeyPairByNameHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
@ -353,15 +363,15 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testConfigureNode() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("configureNode", int.class,
NodeConfiguration.class);
NodeConfiguration.class);
HttpRequest request = processor.createRequest(method, 12, new NodeConfiguration().changeDescriptionTo("eggs"));
assertRequestLineEquals(request, "PUT https://vcloud/extensions/nodeService/12 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertPayloadEquals(
request,
"<NodeService xmlns=\"urn:tmrk:vCloudExpressExtensions-1.6\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Description>eggs</Description></NodeService>",
"application/vnd.tmrk.vCloud.nodeService+xml", false);
request,
"<NodeService xmlns=\"urn:tmrk:vCloudExpressExtensions-1.6\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Description>eggs</Description></NodeService>",
"application/vnd.tmrk.vCloud.nodeService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class);
assertExceptionParserClassEquals(method, null);
@ -401,12 +411,12 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testGetCustomizationOptionsOfCatalogItem() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getCustomizationOptionsOfCatalogItem",
String.class);
String.class);
HttpRequest request = processor.createRequest(method, 12);
assertRequestLineEquals(request, "GET https://vcloud/extensions/template/12/options/customization HTTP/1.1");
assertNonPayloadHeadersEqual(request,
"Accept: application/vnd.tmrk.vCloud.catalogItemCustomizationParameters+xml\n");
"Accept: application/vnd.tmrk.vCloud.catalogItemCustomizationParameters+xml\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
@ -416,11 +426,11 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
checkFilters(request);
}
public void testListKeyPairs() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("listKeyPairs");
HttpRequest request = processor.createRequest(method);
public void testListKeyPairsInOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("listKeyPairsInOrg", String.class);
HttpRequest request = processor.createRequest(method, "org");
assertRequestLineEquals(request, "GET https://keysList HTTP/1.1");
assertRequestLineEquals(request, "GET https://vcloud.safesecureweb.com/api/v0.8/org/1/keysList HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vcloudExpress.keysList+xml\n");
assertPayloadEquals(request, null, null, false);
@ -431,11 +441,11 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
checkFilters(request);
}
public void testListKeyPairsInOrg() throws SecurityException, NoSuchMethodException, IOException {
public void testListKeyPairsInOrgNull() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("listKeyPairsInOrg", String.class);
HttpRequest request = processor.createRequest(method, "org1");
HttpRequest request = processor.createRequest(method,(String) null);
assertRequestLineEquals(request, "GET https://vcloud/extensions/org/org1/keys HTTP/1.1");
assertRequestLineEquals(request, "GET https://vcloud.safesecureweb.com/api/v0.8/org/1/keysList HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vcloudExpress.keysList+xml\n");
assertPayloadEquals(request, null, null, false);
@ -446,6 +456,12 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
checkFilters(request);
}
@Test(expectedExceptions = ResourceNotFoundException.class)
public void testListKeyPairsInOrgNotFound() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("listKeyPairsInOrg", String.class);
processor.createRequest(method, "org1");
}
public void testGetNode() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getNode", int.class);
HttpRequest request = processor.createRequest(method, 12);
@ -485,9 +501,24 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
// checkFilters(request);
// }
public void testGetKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getKeyPair", URI.class);
HttpRequest request = processor.createRequest(method, URI.create("https://vcloud/extensions/key/12"));
assertRequestLineEquals(request, "GET https://vcloud/extensions/key/12 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/xml\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, KeyPairHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
}
public void testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("deleteKeyPair", int.class);
HttpRequest request = processor.createRequest(method, 12);
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("deleteKeyPair", URI.class);
HttpRequest request = processor.createRequest(method, URI.create("https://vcloud/extensions/key/12"));
assertRequestLineEquals(request, "DELETE https://vcloud/extensions/key/12 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
@ -520,7 +551,7 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
@Override
public ContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("trmk-vcloudexpress", "identity", "credential",
new Properties());
new Properties());
}
@RequiresHttp
@ -528,14 +559,24 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
protected static class TerremarkVCloudRestClientModuleExtension extends TerremarkVCloudExpressRestClientModule {
@Override
protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService,
@Named(PROPERTY_API_VERSION) String version) {
@Named(PROPERTY_API_VERSION) String version) {
return URI.create("https://vcloud/login");
}
@Override
protected void configure() {
super.configure();
bind(OrgNameToKeysListSupplier.class).to(TestOrgNameToKeysListSupplier.class);
}
@Override
protected URI provideOrg(@Org Iterable<NamedResource> orgs) {
return URI.create("https://org");
}
@Override
protected String provideOrgName(@Org Iterable<NamedResource> orgs) {
return "org";
}
@Override
@ -554,6 +595,51 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
return null;
}
@Override
protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final VCloudLoginAsyncClient login) {
return Suppliers.<VCloudSession> ofInstance(new VCloudSession() {
@Override
public Map<String, NamedResource> getOrgs() {
return ImmutableMap.<String, NamedResource> of("org", new NamedResourceImpl("1", "org",
VCloudMediaType.ORG_XML, URI.create("https://vcloud.safesecureweb.com/api/v0.8/org/1")));
}
@Override
public String getVCloudToken() {
return "token";
}
});
}
@Singleton
public static class TestOrgNameToKeysListSupplier extends OrgNameToKeysListSupplier {
@Inject
protected TestOrgNameToKeysListSupplier(Supplier<VCloudSession> sessionSupplier) {
super(sessionSupplier, null);
}
@Override
public Map<String, NamedResource> get() {
return Maps.transformValues(sessionSupplier.get().getOrgs(), new Function<NamedResource, NamedResource>() {
@SuppressWarnings("deprecation")
@Override
public NamedResource apply(NamedResource from) {
return new NamedResourceImpl(from.getId(), from.getName(),
TerremarkVCloudExpressMediaType.KEYSLIST_XML, URI.create(from.getLocation().toASCIIString()
+ "/keysList"));
}
});
}
}
@Override
protected URI provideDefaultTasksList(Organization org) {
return URI.create("https://taskslist");
@ -568,12 +654,6 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
protected URI provideDefaultNetwork(VCloudClient client) {
return URI.create("https://vcloud.safesecureweb.com/network/1990");
}
@Override
protected URI provideDefaultKeysList(Organization org) {
return URI.create("https://keysList");
}
}
}

View File

@ -65,7 +65,7 @@ public class TerremarkVCloudComputeServiceLiveTest extends VCloudComputeServiceL
public void testAssignability() throws Exception {
@SuppressWarnings("unused")
RestContext<TerremarkVCloudExpressClient, TerremarkVCloudExpressAsyncClient> tmContext = new ComputeServiceContextFactory()
.createContext(provider, identity, credential).getProviderSpecificContext();
.createContext(provider, identity, credential).getProviderSpecificContext();
}
@Override

View File

@ -23,6 +23,7 @@ import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import java.net.URI;
import java.util.concurrent.ConcurrentMap;
import org.jclouds.vcloud.terremark.TerremarkVCloudExpressClient;
@ -46,8 +47,7 @@ public class DeleteKeyPairTest {
DeleteKeyPair strategy = setupStrategy();
// setup expectations
expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg()))
.andReturn(ImmutableSet.<KeyPair> of());
expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg())).andReturn(ImmutableSet.<KeyPair> of());
// replay mocks
replayStrategy(strategy);
@ -68,12 +68,10 @@ public class DeleteKeyPairTest {
KeyPair keyPair = createMock(KeyPair.class);
// setup expectations
expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg()))
.andReturn(ImmutableSet.<KeyPair> of(keyPair));
expect(keyPair.getName()).andReturn(
"jclouds#" + orgTag.getName() + "-123").atLeastOnce();
expect(keyPair.getId()).andReturn(1234);
strategy.terremarkClient.deleteKeyPair(1234);
expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg())).andReturn(ImmutableSet.<KeyPair> of(keyPair));
expect(keyPair.getName()).andReturn("jclouds#" + orgTag.getName() + "-123").atLeastOnce();
expect(keyPair.getLocation()).andReturn(URI.create("1245"));
strategy.terremarkClient.deleteKeyPair(URI.create("1245"));
expect(strategy.credentialsMap.remove(orgTag)).andReturn(null);
// replay mocks
@ -97,10 +95,8 @@ public class DeleteKeyPairTest {
KeyPair keyPair = createMock(KeyPair.class);
// setup expectations
expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg()))
.andReturn(ImmutableSet.<KeyPair> of(keyPair));
expect(keyPair.getName()).andReturn(
"kclouds#" + orgTag.getName() + "-123");
expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg())).andReturn(ImmutableSet.<KeyPair> of(keyPair));
expect(keyPair.getName()).andReturn("kclouds#" + orgTag.getName() + "-123");
// replay mocks
replay(keyPair);

View File

@ -0,0 +1,70 @@
/**
*
* 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.terremark.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.URI;
import java.net.UnknownHostException;
import org.jclouds.http.functions.BaseHandlerTest;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.vcloud.terremark.domain.KeyPair;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code KeyPairByNameHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "vcloud.KeyPairByNameHandlerTest")
public class KeyPairByNameHandlerTest extends BaseHandlerTest {
public void testGood() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/terremark/keysList.xml");
KeyPair result = factory.create(
addOrgAndNameToHandler(injector.getInstance(KeyPairByNameHandler.class), "org", "default")).parse(is);
assertEquals(result, new KeyPair(9, URI
.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/extensions/key/9"), "default", true,
null, "4e:af:8a:9f:e9:d2:72:d7:4b:a0:da:98:72:98:4d:7d"));
}
public void testNotFound() throws UnknownHostException {
InputStream is = getClass().getResourceAsStream("/terremark/keysList.xml");
KeyPair result = factory.create(
addOrgAndNameToHandler(injector.getInstance(KeyPairByNameHandler.class), "org", "monster")).parse(is);
assertEquals(result, null);
}
private static KeyPairByNameHandler addOrgAndNameToHandler(KeyPairByNameHandler handler, String org, String name) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { org, name }).anyTimes();
replay(request);
handler.setContext(request);
return handler;
}
}