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

View File

@ -37,21 +37,35 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
* Provides access to VCloud resources via their REST API. * Provides access to VCloud resources via their REST API.
* <p/> * <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 * @author Adrian Cole
*/ */
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface VCloudClient { public interface VCloudClient {
/** /**
* This call returns a list of all vCloud Data Centers (vdcs), catalogs, and task lists within * Please use {@link #getOrganizationNamed(String)} passing null
* the organization.
*/ */
@Deprecated
Organization getDefaultOrganization(); Organization getDefaultOrganization();
/**
* Please use #getOrganizationByName
*/
@Deprecated
Organization getOrganization(String orgId); 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 getDefaultCatalog();
Catalog getCatalog(String catalogId); Catalog getCatalog(String catalogId);
CatalogItem getCatalogItem(String catalogItemId); CatalogItem getCatalogItem(String catalogItemId);
@ -75,12 +89,14 @@ public interface VCloudClient {
Task undeployVApp(String vAppId); 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); 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); Task powerOffVApp(String vAppId);
@ -106,8 +122,7 @@ public interface VCloudClient {
VApp getVApp(String appId); VApp getVApp(String appId);
VApp instantiateVAppTemplateInVDC(String vDCId, String appName, String templateId, VApp instantiateVAppTemplateInVDC(String vDCId, String appName, String templateId,
InstantiateVAppTemplateOptions... options); InstantiateVAppTemplateOptions... options);
Task cloneVAppInVDC(String vDCId, String vAppIdToClone, String newName, Task cloneVAppInVDC(String vDCId, String vAppIdToClone, String newName, CloneVAppOptions... options);
CloneVAppOptions... options);
} }

View File

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

View File

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

View File

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

View File

@ -32,6 +32,11 @@ import com.google.inject.ImplementedBy;
*/ */
@ImplementedBy(NamedResourceImpl.class) @ImplementedBy(NamedResourceImpl.class)
public interface NamedResource extends Comparable<NamedResource> { public interface NamedResource extends Comparable<NamedResource> {
/**
* name is not a safe means to identify a resource. Please use name.
*/
@Deprecated
String getId(); String getId();
String getName(); 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") @SuppressWarnings("unchecked")
@Override @Override
public Future<Organization> apply(Location from) { 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"); }, 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_API_VERSION;
import static org.jclouds.Constants.PROPERTY_IDENTITY; 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.jclouds.vcloud.options.InstantiateVAppTemplateOptions.Builder.processorCount;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
@ -27,10 +28,10 @@ import java.io.IOException;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URI; import java.net.URI;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Provider;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
@ -47,8 +48,10 @@ import org.jclouds.util.Utils;
import org.jclouds.vcloud.config.VCloudRestClientModule; import org.jclouds.vcloud.config.VCloudRestClientModule;
import org.jclouds.vcloud.domain.NamedResource; import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.domain.Organization; import org.jclouds.vcloud.domain.Organization;
import org.jclouds.vcloud.domain.internal.NamedResourceImpl;
import org.jclouds.vcloud.endpoints.Org; import org.jclouds.vcloud.endpoints.Org;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie; import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient;
import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient; import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession; import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession;
import org.jclouds.vcloud.options.CloneVAppOptions; import org.jclouds.vcloud.options.CloneVAppOptions;
@ -65,6 +68,8 @@ import org.jclouds.vcloud.xml.VDCHandler;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Supplier; 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.Module;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
@ -196,6 +201,21 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
checkFilters(request); 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 { public void testDefaultCatalog() throws SecurityException, NoSuchMethodException, IOException {
Method method = VCloudAsyncClient.class.getMethod("getDefaultCatalog"); Method method = VCloudAsyncClient.class.getMethod("getDefaultCatalog");
HttpRequest request = processor.createRequest(method); HttpRequest request = processor.createRequest(method);
@ -572,17 +592,25 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
} }
@Override @Override
protected void configure() { protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
super.configure(); final VCloudLoginAsyncClient login) {
bind(SetVCloudTokenCookie.class).toInstance(new SetVCloudTokenCookie(new Provider<String>() { 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"; return "token";
} }
})); });
} }
} }
} }

View File

@ -57,11 +57,11 @@ public class VCloudClientLiveTest {
public void testOrganization() throws Exception { public void testOrganization() throws Exception {
Organization response = connection.getDefaultOrganization(); Organization response = connection.getDefaultOrganization();
assertNotNull(response); assertNotNull(response);
assertNotNull(response.getId()); assertNotNull(response.getName());
assert response.getCatalogs().size() >= 1; assert response.getCatalogs().size() >= 1;
assert response.getTasksLists().size() >= 1; assert response.getTasksLists().size() >= 1;
assert response.getVDCs().size() >= 1; assert response.getVDCs().size() >= 1;
assertEquals(connection.getOrganization(response.getId()), response); assertEquals(connection.getOrganizationNamed(response.getName()), response);
} }
@Test @Test
@ -161,15 +161,14 @@ public class VCloudClientLiveTest {
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() { public void setupClient() {
String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"), String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"), "jclouds.test.endpoint");
"jclouds.test.endpoint");
identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity"); identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential"); String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential");
Properties props = new Properties(); Properties props = new Properties();
props.setProperty("vcloud.endpoint", endpoint); props.setProperty("vcloud.endpoint", endpoint);
context = new RestContextFactory().createContext("vcloud", identity, credential, ImmutableSet context = new RestContextFactory().createContext("vcloud", identity, credential, ImmutableSet
.<Module> of(new Log4JLoggingModule()), props); .<Module> of(new Log4JLoggingModule()), props);
connection = context.getApi(); 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.CATALOG_XML;
import static org.jclouds.vcloud.VCloudMediaType.ORG_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.VAPP_XML;
import static org.jclouds.vcloud.VCloudMediaType.VDC_XML; import static org.jclouds.vcloud.VCloudMediaType.VDC_XML;
import static org.jclouds.vcloud.terremark.TerremarkVCloudMediaType.CATALOGITEMCUSTOMIZATIONPARAMETERS_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 java.util.Set;
import javax.annotation.Nullable;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
import javax.ws.rs.GET; import javax.ws.rs.GET;
@ -43,6 +45,7 @@ import javax.ws.rs.Produces;
import org.jclouds.predicates.validators.DnsNameValidator; import org.jclouds.predicates.validators.DnsNameValidator;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.Endpoint;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder; import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.MapPayloadParam; 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.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.vcloud.VCloudAsyncClient; import org.jclouds.vcloud.VCloudAsyncClient;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.domain.Catalog; import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.VDC; import org.jclouds.vcloud.domain.VDC;
import org.jclouds.vcloud.endpoints.Org; import org.jclouds.vcloud.endpoints.Org;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie; 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.VAppId;
import org.jclouds.vcloud.functions.VAppTemplateIdToUri; import org.jclouds.vcloud.functions.VAppTemplateIdToUri;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; 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.TerremarkOrgHandler;
import org.jclouds.vcloud.terremark.xml.TerremarkVDCHandler; import org.jclouds.vcloud.terremark.xml.TerremarkVDCHandler;
import org.jclouds.vcloud.xml.CatalogHandler; import org.jclouds.vcloud.xml.CatalogHandler;
import org.jclouds.vcloud.xml.TaskHandler;
import org.jclouds.vcloud.xml.VAppHandler; import org.jclouds.vcloud.xml.VAppHandler;
import com.google.common.util.concurrent.ListenableFuture; 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. * Provides access to VCloud resources via their REST API.
* <p/> * <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 * @author Adrian Cole
*/ */
@RequestFilters(SetVCloudTokenCookie.class) @RequestFilters(SetVCloudTokenCookie.class)
@ -117,6 +123,16 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@Consumes(ORG_XML) @Consumes(ORG_XML)
ListenableFuture<? extends TerremarkOrganization> getOrganization(@PathParam("orgId") String orgId); 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 * @see TerremarkVCloudExpressClient#getDefaultVDC
*/ */
@ -158,9 +174,9 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(VAppHandler.class) @XMLResponseParser(VAppHandler.class)
@MapBinder(TerremarkBindInstantiateVAppTemplateParamsToXmlPayload.class) @MapBinder(TerremarkBindInstantiateVAppTemplateParamsToXmlPayload.class)
ListenableFuture<? extends VApp> instantiateVAppTemplateInVDC(@PathParam("vDCId") String vDCId, ListenableFuture<? extends VApp> instantiateVAppTemplateInVDC(@PathParam("vDCId") String vDCId,
@MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, @MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName,
@MapPayloadParam("template") @ParamParser(VAppTemplateIdToUri.class) String templateId, @MapPayloadParam("template") @ParamParser(VAppTemplateIdToUri.class) String templateId,
InstantiateVAppTemplateOptions... options); InstantiateVAppTemplateOptions... options);
/** /**
* @see TerremarkVCloudExpressClient#addInternetService * @see TerremarkVCloudExpressClient#addInternetService
@ -173,8 +189,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(InternetServiceHandler.class) @XMLResponseParser(InternetServiceHandler.class)
@MapBinder(AddInternetServiceOptions.class) @MapBinder(AddInternetServiceOptions.class)
ListenableFuture<? extends InternetService> addInternetServiceToVDC(@PathParam("vDCId") String vDCId, ListenableFuture<? extends InternetService> addInternetServiceToVDC(@PathParam("vDCId") String vDCId,
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol, @MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options); @MapPayloadParam("port") int port, AddInternetServiceOptions... options);
/** /**
* @see TerremarkVCloudExpressClient#getAllInternetServices * @see TerremarkVCloudExpressClient#getAllInternetServices
@ -198,8 +214,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(InternetServiceHandler.class) @XMLResponseParser(InternetServiceHandler.class)
@MapBinder(AddInternetServiceOptions.class) @MapBinder(AddInternetServiceOptions.class)
ListenableFuture<? extends InternetService> addInternetServiceToExistingIp(@PathParam("ipId") int existingIpId, ListenableFuture<? extends InternetService> addInternetServiceToExistingIp(@PathParam("ipId") int existingIpId,
@MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol, @MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol,
@MapPayloadParam("port") int port, AddInternetServiceOptions... options); @MapPayloadParam("port") int port, AddInternetServiceOptions... options);
/** /**
* @see TerremarkVCloudExpressClient#deletePublicIp * @see TerremarkVCloudExpressClient#deletePublicIp
@ -284,8 +300,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(NodeHandler.class) @XMLResponseParser(NodeHandler.class)
@MapBinder(AddNodeOptions.class) @MapBinder(AddNodeOptions.class)
ListenableFuture<? extends Node> addNode(@PathParam("internetServiceId") int internetServiceId, ListenableFuture<? extends Node> addNode(@PathParam("internetServiceId") int internetServiceId,
@MapPayloadParam("ipAddress") String ipAddress, @MapPayloadParam("name") String name, @MapPayloadParam("ipAddress") String ipAddress, @MapPayloadParam("name") String name,
@MapPayloadParam("port") int port, AddNodeOptions... options); @MapPayloadParam("port") int port, AddNodeOptions... options);
/** /**
* @see TerremarkVCloudExpressClient#getNodes * @see TerremarkVCloudExpressClient#getNodes
@ -319,7 +335,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@Consumes(NODESERVICE_XML) @Consumes(NODESERVICE_XML)
@XMLResponseParser(NodeHandler.class) @XMLResponseParser(NodeHandler.class)
ListenableFuture<? extends Node> configureNode(@PathParam("nodeId") int nodeId, ListenableFuture<? extends Node> configureNode(@PathParam("nodeId") int nodeId,
@BinderParam(BindNodeConfigurationToXmlPayload.class) NodeConfiguration nodeConfiguration); @BinderParam(BindNodeConfigurationToXmlPayload.class) NodeConfiguration nodeConfiguration);
/** /**
* @see TerremarkVCloudExpressClient#deleteNode * @see TerremarkVCloudExpressClient#deleteNode
@ -341,7 +357,7 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@MapBinder(BindVAppConfigurationToXmlPayload.class) @MapBinder(BindVAppConfigurationToXmlPayload.class)
@ResponseParser(ParseTaskFromLocationHeader.class) @ResponseParser(ParseTaskFromLocationHeader.class)
ListenableFuture<? extends Task> configureVApp(@PathParam("vAppId") @ParamParser(VAppId.class) VApp vApp, ListenableFuture<? extends Task> configureVApp(@PathParam("vAppId") @ParamParser(VAppId.class) VApp vApp,
VAppConfiguration configuration); VAppConfiguration configuration);
/** /**
* @see TerremarkVCloudExpressClient#getCustomizationOptionsOfCatalogItem * @see TerremarkVCloudExpressClient#getCustomizationOptionsOfCatalogItem
@ -352,6 +368,6 @@ public interface TerremarkVCloudAsyncClient extends VCloudAsyncClient {
@XMLResponseParser(CustomizationParametersHandler.class) @XMLResponseParser(CustomizationParametersHandler.class)
@Consumes(CATALOGITEMCUSTOMIZATIONPARAMETERS_XML) @Consumes(CATALOGITEMCUSTOMIZATIONPARAMETERS_XML)
ListenableFuture<? extends CustomizationParameters> getCustomizationOptionsOfCatalogItem( 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. * Provides access to VCloud resources via their REST API.
* <p/> * <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 * @author Adrian Cole
*/ */
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface TerremarkVCloudClient extends VCloudClient { public interface TerremarkVCloudClient extends VCloudClient {
@Override
TerremarkOrganization getDefaultOrganization(); TerremarkOrganization getDefaultOrganization();
@Override
TerremarkOrganization getOrganization(String orgId); TerremarkOrganization getOrganization(String orgId);
@Override
TerremarkOrganization getOrganizationNamed(String orgName);
CustomizationParameters getCustomizationOptionsOfCatalogItem(String catalogItemId); CustomizationParameters getCustomizationOptionsOfCatalogItem(String catalogItemId);
/** /**
@ -68,20 +73,21 @@ public interface TerremarkVCloudClient extends VCloudClient {
PublicIpAddress activatePublicIpInVDC(String vDCId); PublicIpAddress activatePublicIpInVDC(String vDCId);
/** /**
* The call creates a new internet server, including protocol and port information. The public IP * The call creates a new internet server, including protocol and port
* is dynamically allocated. * information. The public IP is dynamically allocated.
* *
*/ */
InternetService addInternetServiceToVDC(String vDCId, String serviceName, Protocol protocol, InternetService addInternetServiceToVDC(String vDCId, String serviceName, Protocol protocol, int port,
int port, AddInternetServiceOptions... options); AddInternetServiceOptions... options);
/** /**
* This call adds an internet service to a known, existing public IP. This call is identical to * This call adds an internet service to a known, existing public IP. This
* Add Internet Service except you specify the public IP in the request. * call is identical to Add Internet Service except you specify the public IP
* in the request.
* *
*/ */
InternetService addInternetServiceToExistingIp(int existingIpId, String serviceName, InternetService addInternetServiceToExistingIp(int existingIpId, String serviceName, Protocol protocol, int port,
Protocol protocol, int port, AddInternetServiceOptions... options); AddInternetServiceOptions... options);
void deleteInternetService(int internetServiceId); void deleteInternetService(int internetServiceId);
@ -99,9 +105,10 @@ public interface TerremarkVCloudClient extends VCloudClient {
/** /**
* This call adds a node to an existing internet service. * This call adds a node to an existing internet service.
* <p/> * <p/>
* Every vDC is assigned a network of 60 IP addresses that can be used as nodes. Each node can * Every vDC is assigned a network of 60 IP addresses that can be used as
* associated with multiple internet service. You can get a list of the available IP addresses by * nodes. Each node can associated with multiple internet service. You can
* calling Get IP Addresses for a Network. * get a list of the available IP addresses by calling Get IP Addresses for a
* Network.
* *
* @param internetServiceId * @param internetServiceId
* @param ipAddress * @param ipAddress
@ -110,8 +117,7 @@ public interface TerremarkVCloudClient extends VCloudClient {
* @param options * @param options
* @return * @return
*/ */
Node addNode(int internetServiceId, String ipAddress, String name, int port, Node addNode(int internetServiceId, String ipAddress, String name, int port, AddNodeOptions... options);
AddNodeOptions... options);
Node getNode(int nodeId); Node getNode(int nodeId);
@ -122,8 +128,9 @@ public interface TerremarkVCloudClient extends VCloudClient {
Set<Node> getNodes(int internetServiceId); Set<Node> getNodes(int internetServiceId);
/** /**
* This call configures the settings of an existing vApp by passing the new configuration. The * This call configures the settings of an existing vApp by passing the new
* existing vApp must be in a powered off state (status = 2). * configuration. The existing vApp must be in a powered off state (status =
* 2).
* <p/> * <p/>
* You can change the following items for a vApp. * You can change the following items for a vApp.
* <ol> * <ol>
@ -132,8 +139,9 @@ public interface TerremarkVCloudClient extends VCloudClient {
* <li>Add a virtual disk</li> * <li>Add a virtual disk</li>
* <li>Delete a virtual disk</li> * <li>Delete a virtual disk</li>
* </ol> * </ol>
* You can make more than one change in a single request. For example, you can increase the * You can make more than one change in a single request. For example, you
* number of virtual CPUs and the amount of virtual memory in the same request. * can increase the number of virtual CPUs and the amount of virtual memory
* in the same request.
* *
* @param vApp * @param vApp
* vApp to change in power state off * 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 javax.ws.rs.core.MediaType.APPLICATION_XML;
import static org.jclouds.vcloud.terremark.TerremarkVCloudExpressMediaType.KEYSLIST_XML; import static org.jclouds.vcloud.terremark.TerremarkVCloudExpressMediaType.KEYSLIST_XML;
import java.net.URI;
import java.util.Set; import java.util.Set;
import javax.annotation.Nullable;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; 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.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder; import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.MapPayloadParam; 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.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.terremark.binders.BindCreateKeyToXmlPayload; import org.jclouds.vcloud.terremark.binders.BindCreateKeyToXmlPayload;
import org.jclouds.vcloud.terremark.domain.KeyPair; 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.KeyPairHandler;
import org.jclouds.vcloud.terremark.xml.KeyPairsHandler; 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. * Provides access to VCloud resources via their REST API.
* <p/> * <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 * @author Adrian Cole
*/ */
@RequestFilters(SetVCloudTokenCookie.class) @RequestFilters(SetVCloudTokenCookie.class)
public interface TerremarkVCloudExpressAsyncClient extends TerremarkVCloudAsyncClient { 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 * @see TerremarkVCloudExpressClient#listKeyPairsInOrg
*/ */
@GET @GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/extensions/org/{orgId}/keys")
@Consumes(KEYSLIST_XML) @Consumes(KEYSLIST_XML)
@XMLResponseParser(KeyPairsHandler.class) @XMLResponseParser(KeyPairsHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.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 * @see TerremarkVCloudExpressClient#generateKeyPairInOrg
*/ */
@POST @POST
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/extensions/org/{orgId}/keys")
@Produces(KEYSLIST_XML) @Produces(KEYSLIST_XML)
@Consumes(KEYSLIST_XML) @Consumes(KEYSLIST_XML)
@XMLResponseParser(KeyPairHandler.class) @XMLResponseParser(KeyPairHandler.class)
@MapBinder(BindCreateKeyToXmlPayload.class) @MapBinder(BindCreateKeyToXmlPayload.class)
ListenableFuture<? extends KeyPair> generateKeyPairInOrg(@PathParam("orgId") String orgId, ListenableFuture<? extends KeyPair> generateKeyPairInOrg(
@MapPayloadParam("name") String name, @MapPayloadParam("isDefault") boolean makeDefault); @Nullable @EndpointParam(parser = OrgNameToKeysListEndpoint.class) String orgName,
@MapPayloadParam("name") String name, @MapPayloadParam("isDefault") boolean makeDefault);
/** /**
* @see TerremarkVCloudExpressClient#getKeyPair * @see TerremarkVCloudExpressClient#getKeyPair
*/ */
@GET @GET
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/extensions/key/{keyId}")
@XMLResponseParser(KeyPairHandler.class) @XMLResponseParser(KeyPairHandler.class)
@Consumes(APPLICATION_XML) @Consumes(APPLICATION_XML)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @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 // TODO
// /** // /**
@ -123,9 +121,7 @@ public interface TerremarkVCloudExpressAsyncClient extends TerremarkVCloudAsyncC
* @see TerremarkVCloudExpressClient#deleteKeyPair * @see TerremarkVCloudExpressClient#deleteKeyPair
*/ */
@DELETE @DELETE
@Endpoint(org.jclouds.vcloud.endpoints.VCloudApi.class)
@Path("/extensions/key/{keyId}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class) @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; package org.jclouds.vcloud.terremark;
import java.net.URI;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.vcloud.terremark.domain.KeyPair; import org.jclouds.vcloud.terremark.domain.KeyPair;
/** /**
* Provides access to VCloud resources via their REST API. * Provides access to VCloud resources via their REST API.
* <p/> * <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 * @author Adrian Cole
*/ */
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface TerremarkVCloudExpressClient extends TerremarkVCloudClient { 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 // TODO
// KeyPair configureKeyPair(int keyPairId, KeyPairConfiguration // KeyPair configureKeyPair(int keyPairId, KeyPairConfiguration
// keyPairConfiguration); // keyPairConfiguration);
void deleteKeyPair(int keyPairId); void deleteKeyPair(URI keyPair);
} }

View File

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

View File

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

View File

@ -18,36 +18,48 @@
*/ */
package org.jclouds.vcloud.terremark.config; package org.jclouds.vcloud.terremark.config;
import java.io.IOException; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import java.net.URI;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.concurrent.RetryOnTimeOutExceptionSupplier;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import org.jclouds.vcloud.VCloudAsyncClient; import org.jclouds.vcloud.VCloudAsyncClient;
import org.jclouds.vcloud.VCloudClient; 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.TerremarkVCloudAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient; import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudExpressAsyncClient; import org.jclouds.vcloud.terremark.TerremarkVCloudExpressAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudExpressClient; import org.jclouds.vcloud.terremark.TerremarkVCloudExpressClient;
import org.jclouds.vcloud.terremark.domain.TerremarkOrganization;
import org.jclouds.vcloud.terremark.endpoints.KeysList; 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; 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 * @author Adrian Cole
*/ */
@RequiresHttp @RequiresHttp
@ConfiguresRestClient @ConfiguresRestClient
public class TerremarkVCloudExpressRestClientModule extends public class TerremarkVCloudExpressRestClientModule extends
TerremarkRestClientModule<TerremarkVCloudExpressClient, TerremarkVCloudExpressAsyncClient> { TerremarkRestClientModule<TerremarkVCloudExpressClient, TerremarkVCloudExpressAsyncClient> {
public TerremarkVCloudExpressRestClientModule() { public TerremarkVCloudExpressRestClientModule() {
super(TerremarkVCloudExpressClient.class, TerremarkVCloudExpressAsyncClient.class); super(TerremarkVCloudExpressClient.class, TerremarkVCloudExpressAsyncClient.class);
@ -77,11 +89,63 @@ public class TerremarkVCloudExpressRestClientModule extends
return in; return in;
} }
@Provides
@KeysList
@Singleton @Singleton
protected URI provideDefaultKeysList(Organization org) { public static class OrgNameToKeysListSupplier implements Supplier<Map<String, NamedResource>> {
return TerremarkOrganization.class.cast(org).getKeysList().getLocation(); 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 @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 { try {
String content = parseErrorFromContentOrNull(command, response); String content = parseErrorFromContentOrNull(command, response);
switch (response.getStatusCode()) { switch (response.getStatusCode()) {
case 401: case 401:
exception = new AuthorizationException(command.getRequest(), content); exception = new AuthorizationException(command.getRequest(), content);
break; break;
case 403: // TODO temporary as terremark mistakenly uses this for vApp not found. case 403: // TODO temporary as terremark mistakenly uses this for vApp
case 404: // not found.
if (!command.getRequest().getMethod().equals("DELETE")) { case 404:
String path = command.getRequest().getEndpoint().getPath(); if (!command.getRequest().getMethod().equals("DELETE")) {
Matcher matcher = RESOURCE_PATTERN.matcher(path); String path = command.getRequest().getEndpoint().getPath();
String message; Matcher matcher = RESOURCE_PATTERN.matcher(path);
if (matcher.find()) { String message;
message = String.format("%s %s not found", matcher.group(1), matcher.group(2)); if (matcher.find()) {
} else { message = String.format("%s %s not found", matcher.group(1), matcher.group(2));
message = path; } else {
} message = path;
exception = new ResourceNotFoundException(message);
} }
break; exception = new ResourceNotFoundException(message);
case 500: }
if (response.getMessage().indexOf("because there is a pending task running") != -1) break;
exception = new IllegalStateException(response.getMessage(), exception); case 500:
break; if (response.getMessage().indexOf("because there is a pending task running") != -1)
default: exception = new IllegalStateException(response.getMessage(), exception);
exception = new HttpResponseException(command, response, content); 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 { } finally {
releasePayload(response); 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; private NamedResource keysList;
public TerremarkOrganization getResult() { public TerremarkOrganization getResult() {
return new TerremarkOrganizationImpl(org.getId(), org.getName(), org.getLocation(), catalogs, return new TerremarkOrganizationImpl(org.getId(), org.getName(), org.getLocation(), catalogs, vdcs, tasksLists,
vdcs, tasksLists, keysList); keysList);
} }
@Override @Override
public void startElement(String uri, String localName, String qName, Attributes attributes) public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
throws SAXException {
super.startElement(uri, localName, qName, attributes); super.startElement(uri, localName, qName, attributes);
if (qName.equals("Link")) { if (qName.equals("Link")) {
int typeIndex = attributes.getIndex("type"); int typeIndex = attributes.getIndex("type");

View File

@ -48,10 +48,10 @@ public class TerremarkVCloudClientLiveTest extends TerremarkClientLiveTest {
public void testKeysList() throws Exception { public void testKeysList() throws Exception {
TerremarkVCloudExpressClient vCloudExpressClient = TerremarkVCloudExpressClient.class.cast(tmClient); TerremarkVCloudExpressClient vCloudExpressClient = TerremarkVCloudExpressClient.class.cast(tmClient);
TerremarkOrganization org = vCloudExpressClient.getDefaultOrganization(); TerremarkOrganization org = vCloudExpressClient.getDefaultOrganization();
Set<KeyPair> response = vCloudExpressClient.listKeyPairs(); Set<KeyPair> response = vCloudExpressClient.listKeyPairsInOrg(null);
assertNotNull(response); assertNotNull(response);
System.err.println(response); System.err.println(response);
assertEquals(response, vCloudExpressClient.listKeyPairsInOrg(org.getId())); assertEquals(response, vCloudExpressClient.listKeyPairsInOrg(org.getName()));
} }
@Override @Override
@ -59,21 +59,22 @@ public class TerremarkVCloudClientLiveTest extends TerremarkClientLiveTest {
TerremarkVCloudExpressClient vCloudExpressClient = TerremarkVCloudExpressClient.class.cast(tmClient); TerremarkVCloudExpressClient vCloudExpressClient = TerremarkVCloudExpressClient.class.cast(tmClient);
TerremarkOrganization org = vCloudExpressClient.getDefaultOrganization(); TerremarkOrganization org = vCloudExpressClient.getDefaultOrganization();
key = vCloudExpressClient.generateKeyPairInOrg(org.getId(), "livetest", false); key = vCloudExpressClient.generateKeyPairInOrg(org.getName(), "livetest", false);
assertNotNull(key); assertNotNull(key);
System.err.println(key); System.err.println(key);
assertEquals(key.getName(), "livetest"); assertEquals(key.getName(), "livetest");
assertNotNull(key.getPrivateKey()); assertNotNull(key.getPrivateKey());
assertNotNull(key.getFingerPrint()); assertNotNull(key.getFingerPrint());
assertEquals(key.isDefault(), false); assertEquals(key.isDefault(), false);
assertEquals(key.getFingerPrint(), vCloudExpressClient.getKeyPair(key.getId()).getFingerPrint()); assertEquals(key.getFingerPrint(), vCloudExpressClient.getKeyPairInOrg(org.getName(), key.getName())
.getFingerPrint());
} }
@AfterTest @AfterTest
void cleanup1() throws InterruptedException, ExecutionException, TimeoutException { void cleanup1() throws InterruptedException, ExecutionException, TimeoutException {
if (key != null) { if (key != null) {
TerremarkVCloudExpressClient vCloudExpressClient = TerremarkVCloudExpressClient.class.cast(tmClient); 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_API_VERSION;
import static org.jclouds.Constants.PROPERTY_IDENTITY; 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.jclouds.vcloud.terremark.options.AddInternetServiceOptions.Builder.disabled;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
@ -27,15 +28,19 @@ import java.io.IOException;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URI; import java.net.URI;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextFactory.ContextSpec; 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.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Utils; import org.jclouds.util.Utils;
import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.domain.NamedResource; import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.domain.Organization; import org.jclouds.vcloud.domain.Organization;
import org.jclouds.vcloud.domain.internal.NamedResourceImpl;
import org.jclouds.vcloud.endpoints.Org; import org.jclouds.vcloud.endpoints.Org;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie; import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient;
import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient; import org.jclouds.vcloud.internal.VCloudVersionsAsyncClient;
import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession; import org.jclouds.vcloud.internal.VCloudLoginAsyncClient.VCloudSession;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions; 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.CustomizationParametersHandler;
import org.jclouds.vcloud.terremark.xml.InternetServiceHandler; import org.jclouds.vcloud.terremark.xml.InternetServiceHandler;
import org.jclouds.vcloud.terremark.xml.InternetServicesHandler; 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.KeyPairsHandler;
import org.jclouds.vcloud.terremark.xml.NodeHandler; import org.jclouds.vcloud.terremark.xml.NodeHandler;
import org.jclouds.vcloud.terremark.xml.NodesHandler; 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.jclouds.vcloud.xml.VAppHandler;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Supplier; 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.Module;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
/** /**
* Tests behavior of {@code TerremarkVCloudAsyncClient} * Tests behavior of {@code TerremarkVCloudExpressAsyncClient}
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "unit", sequential = true, testName = "vcloud.TerremarkVCloudAsyncClientTest") @Test(groups = "unit", sequential = true, testName = "TerremarkVCloudExpressAsyncClientTest")
public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVCloudExpressAsyncClient> { public class TerremarkVCloudExpressAsyncClientTest extends RestClientTest<TerremarkVCloudExpressAsyncClient> {
/** /**
* ignore parameter of catalog id since this doesn't work * 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 { public void testInstantiateVAppTemplate() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", String.class, 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 + ""); HttpRequest request = processor.createRequest(method, "1", "name", 3 + "");
assertRequestLineEquals(request, "POST https://vcloud/vdc/1/action/instantiateVAppTemplate HTTP/1.1"); assertRequestLineEquals(request, "POST https://vcloud/vdc/1/action/instantiateVAppTemplate HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream( assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/InstantiateVAppTemplateParams-test.xml")), "/terremark/InstantiateVAppTemplateParams-test.xml")),
"application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false); "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VAppHandler.class); assertSaxResponseParserClassEquals(method, VAppHandler.class);
@ -149,16 +163,16 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testInstantiateVAppTemplateOptions() throws SecurityException, NoSuchMethodException, IOException { public void testInstantiateVAppTemplateOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", String.class, 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 + "", HttpRequest request = processor.createRequest(method, "1", "name", 3 + "",
TerremarkInstantiateVAppTemplateOptions.Builder.processorCount(2).memory(512).inRow("row").inGroup( TerremarkInstantiateVAppTemplateOptions.Builder.processorCount(2).memory(512).inRow("row").inGroup("group")
"group").withPassword("password").inNetwork(URI.create("http://network"))); .withPassword("password").inNetwork(URI.create("http://network")));
assertRequestLineEquals(request, "POST https://vcloud/vdc/1/action/instantiateVAppTemplate HTTP/1.1"); assertRequestLineEquals(request, "POST https://vcloud/vdc/1/action/instantiateVAppTemplate HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream( assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/InstantiateVAppTemplateParams-options-test.xml")), "/terremark/InstantiateVAppTemplateParams-options-test.xml")),
"application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false); "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VAppHandler.class); assertSaxResponseParserClassEquals(method, VAppHandler.class);
@ -184,14 +198,13 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddInternetService() throws SecurityException, NoSuchMethodException, IOException { public void testAddInternetService() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToVDC", String.class, Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToVDC", String.class,
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0) String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0).getClass());
.getClass());
HttpRequest request = processor.createRequest(method, "1", "name", Protocol.TCP, 22); HttpRequest request = processor.createRequest(method, "1", "name", Protocol.TCP, 22);
assertRequestLineEquals(request, "POST https://vcloud/extensions/vdc/1/internetServices HTTP/1.1"); assertRequestLineEquals(request, "POST https://vcloud/extensions/vdc/1/internetServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream( 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); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InternetServiceHandler.class); assertSaxResponseParserClassEquals(method, InternetServiceHandler.class);
@ -202,16 +215,15 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddInternetServiceOptions() throws SecurityException, NoSuchMethodException, IOException { public void testAddInternetServiceOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToVDC", String.class, Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToVDC", String.class,
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0) String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0).getClass());
.getClass());
HttpRequest request = processor.createRequest(method, "1", "name", Protocol.TCP, 22, disabled().withDescription( 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"); assertRequestLineEquals(request, "POST https://vcloud/extensions/vdc/1/internetServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream( assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/CreateInternetService-options-test.xml")), "/terremark/CreateInternetService-options-test.xml")), "application/vnd.tmrk.vCloud.internetService+xml",
"application/vnd.tmrk.vCloud.internetService+xml", false); false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InternetServiceHandler.class); assertSaxResponseParserClassEquals(method, InternetServiceHandler.class);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
@ -266,14 +278,13 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddInternetServiceToExistingIp() throws SecurityException, NoSuchMethodException, IOException { public void testAddInternetServiceToExistingIp() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToExistingIp", int.class, Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToExistingIp", int.class,
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0) String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0).getClass());
.getClass());
HttpRequest request = processor.createRequest(method, 12, "name", Protocol.TCP, 22); HttpRequest request = processor.createRequest(method, 12, "name", Protocol.TCP, 22);
assertRequestLineEquals(request, "POST https://vcloud/extensions/publicIp/12/internetServices HTTP/1.1"); assertRequestLineEquals(request, "POST https://vcloud/extensions/publicIp/12/internetServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream( 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); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InternetServiceHandler.class); assertSaxResponseParserClassEquals(method, InternetServiceHandler.class);
@ -284,16 +295,15 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddInternetServiceToExistingIpOptions() throws SecurityException, NoSuchMethodException, IOException { public void testAddInternetServiceToExistingIpOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToExistingIp", int.class, Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addInternetServiceToExistingIp", int.class,
String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0) String.class, Protocol.class, int.class, Array.newInstance(AddInternetServiceOptions.class, 0).getClass());
.getClass());
HttpRequest request = processor.createRequest(method, 12, "name", Protocol.TCP, 22, disabled().withDescription( 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"); assertRequestLineEquals(request, "POST https://vcloud/extensions/publicIp/12/internetServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.internetService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream( assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream(
"/terremark/CreateInternetService-options-test.xml")), "/terremark/CreateInternetService-options-test.xml")), "application/vnd.tmrk.vCloud.internetService+xml",
"application/vnd.tmrk.vCloud.internetService+xml", false); false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, InternetServiceHandler.class); assertSaxResponseParserClassEquals(method, InternetServiceHandler.class);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
@ -303,13 +313,13 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddNode() throws SecurityException, NoSuchMethodException, IOException { public void testAddNode() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addNode", int.class, String.class, 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); HttpRequest request = processor.createRequest(method, 12, "10.2.2.2", "name", 22);
assertRequestLineEquals(request, "POST https://vcloud/extensions/internetService/12/nodeServices HTTP/1.1"); assertRequestLineEquals(request, "POST https://vcloud/extensions/internetService/12/nodeServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream( 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); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class); assertSaxResponseParserClassEquals(method, NodeHandler.class);
@ -320,15 +330,15 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testAddNodeOptions() throws SecurityException, NoSuchMethodException, IOException { public void testAddNodeOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("addNode", int.class, String.class, 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 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"); assertRequestLineEquals(request, "POST https://vcloud/extensions/internetService/12/nodeServices HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream( 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); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class); assertSaxResponseParserClassEquals(method, NodeHandler.class);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
@ -336,16 +346,16 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
checkFilters(request); checkFilters(request);
} }
public void testGetKeyPair() throws SecurityException, NoSuchMethodException, IOException { public void testGetKeyPairInOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getNode", int.class); Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getKeyPairInOrg", String.class, String.class);
HttpRequest request = processor.createRequest(method, 12); HttpRequest request = processor.createRequest(method, "org", "keyPair");
assertRequestLineEquals(request, "GET https://vcloud/extensions/nodeService/12 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.vCloud.nodeService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vcloudExpress.keysList+xml\n");
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class); assertSaxResponseParserClassEquals(method, KeyPairByNameHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request); checkFilters(request);
@ -353,15 +363,15 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testConfigureNode() throws SecurityException, NoSuchMethodException, IOException { public void testConfigureNode() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("configureNode", int.class, Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("configureNode", int.class,
NodeConfiguration.class); NodeConfiguration.class);
HttpRequest request = processor.createRequest(method, 12, new NodeConfiguration().changeDescriptionTo("eggs")); HttpRequest request = processor.createRequest(method, 12, new NodeConfiguration().changeDescriptionTo("eggs"));
assertRequestLineEquals(request, "PUT https://vcloud/extensions/nodeService/12 HTTP/1.1"); assertRequestLineEquals(request, "PUT https://vcloud/extensions/nodeService/12 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vCloud.nodeService+xml\n");
assertPayloadEquals( assertPayloadEquals(
request, request,
"<NodeService xmlns=\"urn:tmrk:vCloudExpressExtensions-1.6\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Description>eggs</Description></NodeService>", "<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); "application/vnd.tmrk.vCloud.nodeService+xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, NodeHandler.class); assertSaxResponseParserClassEquals(method, NodeHandler.class);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
@ -401,12 +411,12 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
public void testGetCustomizationOptionsOfCatalogItem() throws SecurityException, NoSuchMethodException, IOException { public void testGetCustomizationOptionsOfCatalogItem() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getCustomizationOptionsOfCatalogItem", Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getCustomizationOptionsOfCatalogItem",
String.class); String.class);
HttpRequest request = processor.createRequest(method, 12); HttpRequest request = processor.createRequest(method, 12);
assertRequestLineEquals(request, "GET https://vcloud/extensions/template/12/options/customization HTTP/1.1"); assertRequestLineEquals(request, "GET https://vcloud/extensions/template/12/options/customization HTTP/1.1");
assertNonPayloadHeadersEqual(request, assertNonPayloadHeadersEqual(request,
"Accept: application/vnd.tmrk.vCloud.catalogItemCustomizationParameters+xml\n"); "Accept: application/vnd.tmrk.vCloud.catalogItemCustomizationParameters+xml\n");
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
@ -416,11 +426,11 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
checkFilters(request); checkFilters(request);
} }
public void testListKeyPairs() throws SecurityException, NoSuchMethodException, IOException { public void testListKeyPairsInOrg() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("listKeyPairs"); Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("listKeyPairsInOrg", String.class);
HttpRequest request = processor.createRequest(method); 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"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vcloudExpress.keysList+xml\n");
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
@ -431,11 +441,11 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
checkFilters(request); checkFilters(request);
} }
public void testListKeyPairsInOrg() throws SecurityException, NoSuchMethodException, IOException { public void testListKeyPairsInOrgNull() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("listKeyPairsInOrg", String.class); 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"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.tmrk.vcloudExpress.keysList+xml\n");
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
@ -446,6 +456,12 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
checkFilters(request); 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 { public void testGetNode() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getNode", int.class); Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("getNode", int.class);
HttpRequest request = processor.createRequest(method, 12); HttpRequest request = processor.createRequest(method, 12);
@ -485,9 +501,24 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
// checkFilters(request); // 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 { public void testDeleteKeyPair() throws SecurityException, NoSuchMethodException, IOException {
Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("deleteKeyPair", int.class); Method method = TerremarkVCloudExpressAsyncClient.class.getMethod("deleteKeyPair", URI.class);
HttpRequest request = processor.createRequest(method, 12); HttpRequest request = processor.createRequest(method, URI.create("https://vcloud/extensions/key/12"));
assertRequestLineEquals(request, "DELETE https://vcloud/extensions/key/12 HTTP/1.1"); assertRequestLineEquals(request, "DELETE https://vcloud/extensions/key/12 HTTP/1.1");
assertNonPayloadHeadersEqual(request, ""); assertNonPayloadHeadersEqual(request, "");
@ -520,7 +551,7 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
@Override @Override
public ContextSpec<?, ?> createContextSpec() { public ContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("trmk-vcloudexpress", "identity", "credential", return new RestContextFactory().createContextSpec("trmk-vcloudexpress", "identity", "credential",
new Properties()); new Properties());
} }
@RequiresHttp @RequiresHttp
@ -528,14 +559,24 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
protected static class TerremarkVCloudRestClientModuleExtension extends TerremarkVCloudExpressRestClientModule { protected static class TerremarkVCloudRestClientModuleExtension extends TerremarkVCloudExpressRestClientModule {
@Override @Override
protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService, protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService,
@Named(PROPERTY_API_VERSION) String version) { @Named(PROPERTY_API_VERSION) String version) {
return URI.create("https://vcloud/login"); return URI.create("https://vcloud/login");
} }
@Override
protected void configure() {
super.configure();
bind(OrgNameToKeysListSupplier.class).to(TestOrgNameToKeysListSupplier.class);
}
@Override @Override
protected URI provideOrg(@Org Iterable<NamedResource> orgs) { protected URI provideOrg(@Org Iterable<NamedResource> orgs) {
return URI.create("https://org"); return URI.create("https://org");
}
@Override
protected String provideOrgName(@Org Iterable<NamedResource> orgs) {
return "org";
} }
@Override @Override
@ -554,6 +595,51 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
return null; 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 @Override
protected URI provideDefaultTasksList(Organization org) { protected URI provideDefaultTasksList(Organization org) {
return URI.create("https://taskslist"); return URI.create("https://taskslist");
@ -568,12 +654,6 @@ public class TerremarkVCloudAsyncClientTest extends RestClientTest<TerremarkVClo
protected URI provideDefaultNetwork(VCloudClient client) { protected URI provideDefaultNetwork(VCloudClient client) {
return URI.create("https://vcloud.safesecureweb.com/network/1990"); 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 { public void testAssignability() throws Exception {
@SuppressWarnings("unused") @SuppressWarnings("unused")
RestContext<TerremarkVCloudExpressClient, TerremarkVCloudExpressAsyncClient> tmContext = new ComputeServiceContextFactory() RestContext<TerremarkVCloudExpressClient, TerremarkVCloudExpressAsyncClient> tmContext = new ComputeServiceContextFactory()
.createContext(provider, identity, credential).getProviderSpecificContext(); .createContext(provider, identity, credential).getProviderSpecificContext();
} }
@Override @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.replay;
import static org.easymock.classextension.EasyMock.verify; import static org.easymock.classextension.EasyMock.verify;
import java.net.URI;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import org.jclouds.vcloud.terremark.TerremarkVCloudExpressClient; import org.jclouds.vcloud.terremark.TerremarkVCloudExpressClient;
@ -46,8 +47,7 @@ public class DeleteKeyPairTest {
DeleteKeyPair strategy = setupStrategy(); DeleteKeyPair strategy = setupStrategy();
// setup expectations // setup expectations
expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg())) expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg())).andReturn(ImmutableSet.<KeyPair> of());
.andReturn(ImmutableSet.<KeyPair> of());
// replay mocks // replay mocks
replayStrategy(strategy); replayStrategy(strategy);
@ -68,12 +68,10 @@ public class DeleteKeyPairTest {
KeyPair keyPair = createMock(KeyPair.class); KeyPair keyPair = createMock(KeyPair.class);
// setup expectations // setup expectations
expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg())) expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg())).andReturn(ImmutableSet.<KeyPair> of(keyPair));
.andReturn(ImmutableSet.<KeyPair> of(keyPair)); expect(keyPair.getName()).andReturn("jclouds#" + orgTag.getName() + "-123").atLeastOnce();
expect(keyPair.getName()).andReturn( expect(keyPair.getLocation()).andReturn(URI.create("1245"));
"jclouds#" + orgTag.getName() + "-123").atLeastOnce(); strategy.terremarkClient.deleteKeyPair(URI.create("1245"));
expect(keyPair.getId()).andReturn(1234);
strategy.terremarkClient.deleteKeyPair(1234);
expect(strategy.credentialsMap.remove(orgTag)).andReturn(null); expect(strategy.credentialsMap.remove(orgTag)).andReturn(null);
// replay mocks // replay mocks
@ -97,10 +95,8 @@ public class DeleteKeyPairTest {
KeyPair keyPair = createMock(KeyPair.class); KeyPair keyPair = createMock(KeyPair.class);
// setup expectations // setup expectations
expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg())) expect(strategy.terremarkClient.listKeyPairsInOrg(orgTag.getOrg())).andReturn(ImmutableSet.<KeyPair> of(keyPair));
.andReturn(ImmutableSet.<KeyPair> of(keyPair)); expect(keyPair.getName()).andReturn("kclouds#" + orgTag.getName() + "-123");
expect(keyPair.getName()).andReturn(
"kclouds#" + orgTag.getName() + "-123");
// replay mocks // replay mocks
replay(keyPair); 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;
}
}