From 72bf4e2d630783feb9add3b03de1d47d5dbe5eb7 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 24 Aug 2010 10:47:39 -0700 Subject: [PATCH] Issue 280: split out vcloud 0.8 operations that are incompatible from 0.9+, split out incompatible VApps and VAppTemplates --- .../vcloud/CommonVCloudAsyncClient.java | 92 +----- .../jclouds/vcloud/CommonVCloudClient.java | 37 +-- .../org/jclouds/vcloud/VCloudAsyncClient.java | 102 ++++++ .../java/org/jclouds/vcloud/VCloudClient.java | 95 ++++++ .../vcloud/VCloudExpressAsyncClient.java | 61 ++++ .../jclouds/vcloud/VCloudExpressClient.java | 32 ++ .../org/jclouds/vcloud/VCloudMediaType.java | 29 ++ .../BindDeployVAppParamsToXmlPayload.java | 45 +++ .../binders/BindParamsToXmlPayload.java | 84 +++++ .../BindUndeployVAppParamsToXmlPayload.java | 45 +++ .../compute/CommonVCloudComputeClient.java | 2 +- ...mmonVCloudComputeServiceContextModule.java | 3 - .../VCloudComputeServiceContextModule.java | 3 + ...oudExpressComputeServiceContextModule.java | 3 + .../CommonVCloudComputeClientImpl.java | 14 +- .../internal/VCloudComputeClientImpl.java | 29 +- .../VCloudExpressComputeClientImpl.java | 19 +- .../VCloudExpressRebootNodeStrategy.java | 61 ++++ .../strategy/VCloudRebootNodeStrategy.java | 8 +- .../java/org/jclouds/vcloud/domain/VApp.java | 24 +- .../jclouds/vcloud/domain/VAppTemplate.java | 25 +- .../java/org/jclouds/vcloud/domain/Vm.java | 73 ++++ .../vcloud/domain/internal/VAppImpl.java | 58 +++- .../domain/internal/VAppTemplateImpl.java | 19 +- .../vcloud/domain/internal/VmImpl.java | 159 +++++++++ .../org/jclouds/vcloud/xml/VAppHandler.java | 78 +++-- .../vcloud/xml/VAppTemplateHandler.java | 38 ++- .../org/jclouds/vcloud/xml/VmHandler.java | 100 ++++++ .../jclouds/vcloud/VCloudAsyncClientTest.java | 312 ++++++++++++------ .../jclouds/vcloud/VCloudClientLiveTest.java | 19 ++ .../vcloud/VCloudExpressAsyncClientTest.java | 14 +- .../BindDeployVAppParamsToXmlPayloadTest.java | 90 +++++ ...indUndeployVAppParamsToXmlPayloadTest.java | 90 +++++ .../jclouds/vcloud/xml/VAppHandlerTest.java | 76 +++++ .../vcloud/xml/VAppTemplateHandlerTest.java | 22 +- .../org/jclouds/vcloud/xml/VmHandlerTest.java | 64 ++++ ...markVCloudComputeServiceContextModule.java | 4 +- 37 files changed, 1719 insertions(+), 310 deletions(-) create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindDeployVAppParamsToXmlPayload.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindParamsToXmlPayload.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindUndeployVAppParamsToXmlPayload.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudExpressRebootNodeStrategy.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/domain/Vm.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VmImpl.java create mode 100644 vcloud/core/src/main/java/org/jclouds/vcloud/xml/VmHandler.java create mode 100644 vcloud/core/src/test/java/org/jclouds/vcloud/binders/BindDeployVAppParamsToXmlPayloadTest.java create mode 100644 vcloud/core/src/test/java/org/jclouds/vcloud/binders/BindUndeployVAppParamsToXmlPayloadTest.java create mode 100644 vcloud/core/src/test/java/org/jclouds/vcloud/xml/VAppHandlerTest.java create mode 100644 vcloud/core/src/test/java/org/jclouds/vcloud/xml/VmHandlerTest.java diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/CommonVCloudAsyncClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/CommonVCloudAsyncClient.java index 731055b628..5a88f57787 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/CommonVCloudAsyncClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/CommonVCloudAsyncClient.java @@ -77,7 +77,7 @@ import com.google.common.util.concurrent.ListenableFuture; public interface CommonVCloudAsyncClient { /** - * @see VCloudClient#getOrg + * @see CommonVCloudClient#getOrg */ @GET @XMLResponseParser(OrgHandler.class) @@ -86,7 +86,7 @@ public interface CommonVCloudAsyncClient { ListenableFuture getOrg(@EndpointParam URI orgId); /** - * @see VCloudClient#getOrgNamed + * @see CommonVCloudClient#getOrgNamed */ @GET @XMLResponseParser(OrgHandler.class) @@ -96,7 +96,7 @@ public interface CommonVCloudAsyncClient { @Nullable @EndpointParam(parser = OrgNameToEndpoint.class) String orgName); /** - * @see VCloudClient#getCatalog + * @see CommonVCloudClient#getCatalog */ @GET @XMLResponseParser(CatalogHandler.class) @@ -105,7 +105,7 @@ public interface CommonVCloudAsyncClient { ListenableFuture getCatalog(@EndpointParam URI catalogId); /** - * @see VCloudClient#findCatalogInOrgNamed + * @see CommonVCloudClient#findCatalogInOrgNamed */ @GET @XMLResponseParser(CatalogHandler.class) @@ -116,7 +116,7 @@ public interface CommonVCloudAsyncClient { @Nullable @EndpointParam(parser = OrgNameAndCatalogNameToEndpoint.class) String catalogName); /** - * @see VCloudClient#getCatalogItem + * @see CommonVCloudClient#getCatalogItem */ @GET @Consumes(CATALOGITEM_XML) @@ -125,7 +125,7 @@ public interface CommonVCloudAsyncClient { ListenableFuture getCatalogItem(@EndpointParam URI catalogItem); /** - * @see VCloudClient#getCatalogItemInOrg + * @see CommonVCloudClient#getCatalogItemInOrg */ @GET @Consumes(CATALOGITEM_XML) @@ -137,7 +137,7 @@ public interface CommonVCloudAsyncClient { @EndpointParam(parser = OrgNameCatalogNameItemNameToEndpoint.class) String itemName); /** - * @see VCloudClient#findNetworkInOrgVDCNamed + * @see CommonVCloudClient#findNetworkInOrgVDCNamed */ @GET @Consumes(NETWORK_XML) @@ -149,7 +149,7 @@ public interface CommonVCloudAsyncClient { @EndpointParam(parser = OrgNameVDCNameResourceEntityNameToEndpoint.class) String networkName); /** - * @see VCloudClient#getNetwork + * @see CommonVCloudClient#getNetwork */ @GET @Consumes(NETWORK_XML) @@ -158,7 +158,7 @@ public interface CommonVCloudAsyncClient { ListenableFuture getNetwork(@EndpointParam URI network); /** - * @see VCloudClient#getVDC(URI) + * @see CommonVCloudClient#getVDC(URI) */ @GET @XMLResponseParser(VDCHandler.class) @@ -167,7 +167,7 @@ public interface CommonVCloudAsyncClient { ListenableFuture getVDC(@EndpointParam URI vdc); /** - * @see VCloudClient#findVDCInOrgNamed(String, String) + * @see CommonVCloudClient#findVDCInOrgNamed(String, String) */ @GET @XMLResponseParser(VDCHandler.class) @@ -178,7 +178,7 @@ public interface CommonVCloudAsyncClient { @Nullable @EndpointParam(parser = OrgNameAndVDCNameToEndpoint.class) String vdcName); /** - * @see VCloudClient#getTasksList + * @see CommonVCloudClient#getTasksList */ @GET @Consumes(TASKSLIST_XML) @@ -187,7 +187,7 @@ public interface CommonVCloudAsyncClient { ListenableFuture getTasksList(@EndpointParam URI tasksListId); /** - * @see VCloudClient#findTasksListInOrgNamed + * @see CommonVCloudClient#findTasksListInOrgNamed */ @GET @Consumes(TASKSLIST_XML) @@ -197,75 +197,15 @@ public interface CommonVCloudAsyncClient { @Nullable @EndpointParam(parser = OrgNameToTasksListEndpoint.class) String orgName); /** - * @see VCloudClient#deployVApp - */ - @POST - @Consumes(TASK_XML) - @Path("/action/deploy") - @XMLResponseParser(TaskHandler.class) - ListenableFuture deployVApp(@EndpointParam URI vAppId); - - /** - * @see VCloudClient#deleteVApp + * @see CommonVCloudClient#deleteVApp */ @DELETE @ExceptionParser(ReturnVoidOnNotFoundOr404.class) ListenableFuture deleteVApp(@EndpointParam URI vAppId); + /** - * @see VCloudClient#undeployVApp - */ - @POST - @Consumes(TASK_XML) - @Path("/action/undeploy") - @XMLResponseParser(TaskHandler.class) - ListenableFuture undeployVApp(@EndpointParam URI vAppId); - - /** - * @see VCloudClient#powerOnVApp - */ - @POST - @Consumes(TASK_XML) - @Path("/power/action/powerOn") - @XMLResponseParser(TaskHandler.class) - ListenableFuture powerOnVApp(@EndpointParam URI vAppId); - - /** - * @see VCloudClient#powerOffVApp - */ - @POST - @Consumes(TASK_XML) - @Path("/power/action/powerOff") - @XMLResponseParser(TaskHandler.class) - ListenableFuture powerOffVApp(@EndpointParam URI vAppId); - - /** - * @see VCloudClient#shutdownVApp - */ - @POST - @Path("/power/action/shutdown") - ListenableFuture shutdownVApp(@EndpointParam URI vAppId); - - /** - * @see VCloudClient#resetVApp - */ - @POST - @Consumes(TASK_XML) - @Path("/power/action/reset") - @XMLResponseParser(TaskHandler.class) - ListenableFuture resetVApp(@EndpointParam URI vAppId); - - /** - * @see VCloudClient#suspendVApp - */ - @POST - @Consumes(TASK_XML) - @Path("/power/action/suspend") - @XMLResponseParser(TaskHandler.class) - ListenableFuture suspendVApp(@EndpointParam URI vAppId); - - /** - * @see VCloudClient#getTask + * @see CommonVCloudClient#getTask */ @GET @Consumes(TASK_XML) @@ -274,7 +214,7 @@ public interface CommonVCloudAsyncClient { ListenableFuture getTask(@EndpointParam URI taskId); /** - * @see VCloudClient#cancelTask + * @see CommonVCloudClient#cancelTask */ @POST @Path("/action/cancel") diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/CommonVCloudClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/CommonVCloudClient.java index 0ef26f4966..5633af97de 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/CommonVCloudClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/CommonVCloudClient.java @@ -113,40 +113,19 @@ public interface CommonVCloudClient { TasksList findTasksListInOrgNamed(String orgName); - Task deployVApp(URI vAppId); - - void deleteVApp(URI vAppId); - - Task undeployVApp(URI vAppId); - /** - * This call powers on the vApp, as specified in the vApp's ovf:Startup element. + * Whenever the result of a request cannot be returned immediately, the server creates a Task + * object and includes it in the response, as a member of the Tasks container in the response + * body. Each Task has an href value, which is a URL that the client can use to retrieve the Task + * element alone, without the rest of the response in which it was contained. All information + * about the task is included in the Task element when it is returned in the response’s Tasks + * container, so a client does not need to make an additional request to the Task URL unless it + * wants to follow the progress of a task that was incomplete. */ - Task powerOnVApp(URI vAppId); - - /** - * This call powers off the vApp, as specified in the vApp's ovf:Startup element. - */ - Task powerOffVApp(URI vAppId); - - /** - * This call shuts down the vApp. - */ - void shutdownVApp(URI vAppId); - - /** - * This call resets the vApp. - */ - Task resetVApp(URI vAppId); - - /** - * This call suspends the vApp. - */ - Task suspendVApp(URI vAppId); - Task getTask(URI taskId); void cancelTask(URI taskId); + void deleteVApp(URI vAppId); } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java index 8ce555b2e1..abb1851818 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java @@ -19,7 +19,9 @@ package org.jclouds.vcloud; +import static org.jclouds.vcloud.VCloudMediaType.DEPLOYVAPPPARAMS_XML; import static org.jclouds.vcloud.VCloudMediaType.TASK_XML; +import static org.jclouds.vcloud.VCloudMediaType.UNDEPLOYVAPPPARAMS_XML; import static org.jclouds.vcloud.VCloudMediaType.VAPPTEMPLATE_XML; import static org.jclouds.vcloud.VCloudMediaType.VAPP_XML; @@ -37,12 +39,15 @@ import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; import org.jclouds.rest.annotations.MapPayloadParam; +import org.jclouds.rest.annotations.MapPayloadParams; import org.jclouds.rest.annotations.ParamValidators; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.vcloud.binders.BindCloneVAppParamsToXmlPayload; +import org.jclouds.vcloud.binders.BindDeployVAppParamsToXmlPayload; import org.jclouds.vcloud.binders.BindInstantiateVCloudExpressVAppTemplateParamsToXmlPayload; +import org.jclouds.vcloud.binders.BindUndeployVAppParamsToXmlPayload; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VAppTemplate; @@ -136,4 +141,101 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VAppHandler.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture getVApp(@EndpointParam URI vApp); + + /** + * @see VCloudClient#deployVAppOrVm + */ + @POST + @Consumes(TASK_XML) + @Produces(DEPLOYVAPPPARAMS_XML) + @Path("/action/deploy") + @MapBinder(BindDeployVAppParamsToXmlPayload.class) + @XMLResponseParser(TaskHandler.class) + ListenableFuture deployVAppOrVm(@EndpointParam URI vAppOrVmId); + + /** + * @see VCloudClient#deployAndPowerOnVAppOrVm + */ + @POST + @Consumes(TASK_XML) + @Produces(DEPLOYVAPPPARAMS_XML) + @Path("/action/deploy") + @MapBinder(BindDeployVAppParamsToXmlPayload.class) + @MapPayloadParams(keys = "powerOn", values = "true") + @XMLResponseParser(TaskHandler.class) + ListenableFuture deployAndPowerOnVAppOrVm(@EndpointParam URI vAppOrVmId); + + /** + * @see VCloudClient#undeployVAppOrVm + */ + @POST + @Consumes(TASK_XML) + @Produces(UNDEPLOYVAPPPARAMS_XML) + @Path("/action/undeploy") + @MapBinder(BindUndeployVAppParamsToXmlPayload.class) + @XMLResponseParser(TaskHandler.class) + ListenableFuture undeployVAppOrVm(@EndpointParam URI vAppOrVmId); + + /** + * @see VCloudClient#undeployAndSaveStateOfVAppOrVm + */ + @POST + @Consumes(TASK_XML) + @Produces(UNDEPLOYVAPPPARAMS_XML) + @Path("/action/undeploy") + @MapBinder(BindUndeployVAppParamsToXmlPayload.class) + @MapPayloadParams(keys = "saveState", values = "true") + @XMLResponseParser(TaskHandler.class) + ListenableFuture undeployAndSaveStateOfVAppOrVm(@EndpointParam URI vAppOrVmId); + + /** + * @see VCloudClient#powerOnVAppOrVm + */ + @POST + @Consumes(TASK_XML) + @Path("/power/action/powerOn") + @XMLResponseParser(TaskHandler.class) + ListenableFuture powerOnVAppOrVm(@EndpointParam URI vAppOrVmId); + + /** + * @see VCloudClient#powerOffVAppOrVm + */ + @POST + @Consumes(TASK_XML) + @Path("/power/action/powerOff") + @XMLResponseParser(TaskHandler.class) + ListenableFuture powerOffVAppOrVm(@EndpointParam URI vAppOrVmId); + + /** + * @see VCloudClient#shutdownVAppOrVm + */ + @POST + @Path("/power/action/shutdown") + ListenableFuture shutdownVAppOrVm(@EndpointParam URI vAppOrVmId); + + /** + * @see VCloudClient#resetVAppOrVm + */ + @POST + @Consumes(TASK_XML) + @Path("/power/action/reset") + @XMLResponseParser(TaskHandler.class) + ListenableFuture resetVAppOrVm(@EndpointParam URI vAppOrVmId); + + /** + * @see VCloudClient#rebootVAppOrVm + */ + @POST + @Path("/power/action/reboot") + ListenableFuture rebootVAppOrVm(@EndpointParam URI vAppOrVmId); + + /** + * @see VCloudClient#suspendVAppOrVm + */ + @POST + @Consumes(TASK_XML) + @Path("/power/action/suspend") + @XMLResponseParser(TaskHandler.class) + ListenableFuture suspendVAppOrVm(@EndpointParam URI vAppOrVmId); + } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java index 7caa1d4b71..96e279f097 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudClient.java @@ -68,4 +68,99 @@ public interface VCloudClient extends CommonVCloudClient { VApp findVAppInOrgVDCNamed(@Nullable String orgName, @Nullable String catalogName, String vAppName); VApp getVApp(URI vApp); + + /** + * To deploy a vApp, the client makes a request to its action/deploy URL. Deploying a vApp + * automatically deploys all of the virtual machines it contains. To deploy a virtual machine, + * the client makes a request to its action/deploy URL. + *

+ * Deploying a Vm implicitly deploys the parent vApp if that vApp is not already deployed. + */ + Task deployVAppOrVm(URI vAppOrVmId); + + /** + * like {@link #deployVAppOrVm(URI)}, except deploy transistions to power on state + * + */ + Task deployAndPowerOnVAppOrVm(URI vAppOrVmId); + + /** + * Undeploying a vApp powers off or suspends any running virtual machines it contains, then frees + * the resources reserved for the vApp and sets the vApp’s deploy attribute to a value of false + * to indicate that it is not deployed. + *

+ * Undeploying a virtual machine powers off or suspends the virtual machine, then frees the + * resources reserved for it and sets the its deploy attribute to a value of false to indicate + * that it is not deployed. This operation has no effect on the containing vApp. + *

NOTE

+ * Using this method will simply power off the vms. In order to save their state, use + * {@link #undeployAndSaveStateOfVAppOrVm} + * + */ + Task undeployVAppOrVm(URI vAppOrVmId); + + /** + * like {@link #undeployVAppOrVm(URI)}, where the undeployed virtual machines are suspended and + * their suspend state saved + * + */ + Task undeployAndSaveStateOfVAppOrVm(URI vAppOrVmId); + + /** + * A powerOn request to a vApp URL powers on all of the virtual machines in the vApp, as + * specified in the vApp’s StartupSection field. + *

+ * A powerOn request to a virtual machine URL powers on the specified virtual machine and forces + * deployment of the parent vApp. + *

+ *

NOTE

A powerOn request to a vApp or virtual machine that is undeployed forces + * deployment. + */ + Task powerOnVAppOrVm(URI vAppOrVmId); + + /** + * A powerOff request to a vApp URL powers off all of the virtual machines in the vApp, as + * specified in its StartupSection field. + *

+ * A powerOff request to a virtual machine URL powers off the specified virtual machine. + */ + Task powerOffVAppOrVm(URI vAppOrVmId); + + /** + * A shutdown request to a vApp URL shuts down all of the virtual machines in the vApp, as + * specified in its StartupSection field. + *

+ * A shutdown request to a virtual machine URL shuts down the specified virtual machine. + *

+ *

NOTE + * A reset request to a virtual machine URL resets the specified virtual machine. + */ + Task resetVAppOrVm(URI vAppOrVmId); + + /** + * A reboot request to a vApp URL reboots all of the virtual machines in the vApp, as specified + * in its StartupSection field. + *

+ * A reboot request to a virtual machine URL reboots the specified virtual machine. + *

+ *

NOTE

Because this request sends a signal to the guest OS, the vCloud API cannot track + * the progress or verify the result of the requested operation. Hence, void is returned + */ + void rebootVAppOrVm(URI vAppOrVmId); + + /** + * A suspend request to a vApp URL suspends all of the virtual machines in the vApp, as specified + * in its StartupSection field. + *

+ * A suspend request to a virtual machine URL suspends the specified virtual machine. + */ + Task suspendVAppOrVm(URI vAppOrVmId); } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudExpressAsyncClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudExpressAsyncClient.java index f7217eec4b..1fd41c5094 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudExpressAsyncClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudExpressAsyncClient.java @@ -161,4 +161,65 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VCloudExpressVAppHandler.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture getVApp(@EndpointParam URI vApp); + + /** + * @see CommonVCloudClient#deployVApp + */ + @POST + @Consumes(TASK_XML) + @Path("/action/deploy") + @XMLResponseParser(TaskHandler.class) + ListenableFuture deployVApp(@EndpointParam URI vAppId); + + /** + * @see CommonVCloudClient#undeployVApp + */ + @POST + @Consumes(TASK_XML) + @Path("/action/undeploy") + @XMLResponseParser(TaskHandler.class) + ListenableFuture undeployVApp(@EndpointParam URI vAppId); + + /** + * @see CommonVCloudClient#powerOnVApp + */ + @POST + @Consumes(TASK_XML) + @Path("/power/action/powerOn") + @XMLResponseParser(TaskHandler.class) + ListenableFuture powerOnVApp(@EndpointParam URI vAppId); + + /** + * @see CommonVCloudClient#powerOffVApp + */ + @POST + @Consumes(TASK_XML) + @Path("/power/action/powerOff") + @XMLResponseParser(TaskHandler.class) + ListenableFuture powerOffVApp(@EndpointParam URI vAppId); + + /** + * @see CommonVCloudClient#shutdownVApp + */ + @POST + @Path("/power/action/shutdown") + ListenableFuture shutdownVApp(@EndpointParam URI vAppId); + + /** + * @see CommonVCloudClient#resetVApp + */ + @POST + @Consumes(TASK_XML) + @Path("/power/action/reset") + @XMLResponseParser(TaskHandler.class) + ListenableFuture resetVApp(@EndpointParam URI vAppId); + + /** + * @see CommonVCloudClient#suspendVApp + */ + @POST + @Consumes(TASK_XML) + @Path("/power/action/suspend") + @XMLResponseParser(TaskHandler.class) + ListenableFuture suspendVApp(@EndpointParam URI vAppId); } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudExpressClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudExpressClient.java index 6a1223f00c..9b6522d039 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudExpressClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudExpressClient.java @@ -69,4 +69,36 @@ public interface VCloudExpressClient extends CommonVCloudClient { VCloudExpressVApp findVAppInOrgVDCNamed(@Nullable String orgName, @Nullable String catalogName, String vAppName); VCloudExpressVApp getVApp(URI vApp); + + Task deployVApp(URI vAppId); + + /** + * + */ + Task undeployVApp(URI vAppId); + + /** + * This call powers on the vApp, as specified in the vApp's ovf:Startup element. + */ + Task powerOnVApp(URI vAppId); + + /** + * This call powers off the vApp, as specified in the vApp's ovf:Startup element. + */ + Task powerOffVApp(URI vAppId); + + /** + * This call shuts down the vApp. + */ + void shutdownVApp(URI vAppId); + + /** + * This call resets the vApp. + */ + Task resetVApp(URI vAppId); + + /** + * This call suspends the vApp. + */ + Task suspendVApp(URI vAppId); } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudMediaType.java b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudMediaType.java index 1d7f54be2a..479a2212d8 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudMediaType.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/VCloudMediaType.java @@ -100,6 +100,26 @@ public interface VCloudMediaType { */ public final static MediaType TASK_XML_TYPE = new MediaType("application", "vnd.vmware.vcloud.task+xml"); + /** + * "application/vnd.vmware.vcloud.undeployVAppParams+xml" + */ + public final static String UNDEPLOYVAPPPARAMS_XML = "application/vnd.vmware.vcloud.undeployVAppParams+xml"; + /** + * "application/vnd.vmware.vcloud.undeployVAppParams+xml" + */ + public final static MediaType UNDEPLOYVAPPPARAMS_XML_TYPE = new MediaType("application", + "vnd.vmware.vcloud.undeployVAppParams+xml"); + + /** + * "application/vnd.vmware.vcloud.deployVAppParams+xml" + */ + public final static String DEPLOYVAPPPARAMS_XML = "application/vnd.vmware.vcloud.deployVAppParams+xml"; + /** + * "application/vnd.vmware.vcloud.deployVAppParams+xml" + */ + public final static MediaType DEPLOYVAPPPARAMS_XML_TYPE = new MediaType("application", + "vnd.vmware.vcloud.deployVAppParams+xml"); + /** * "application/vnd.vmware.vcloud.vApp+xml" */ @@ -109,6 +129,15 @@ public interface VCloudMediaType { */ public final static MediaType VAPP_XML_TYPE = new MediaType("application", "vnd.vmware.vcloud.vApp+xml"); + /** + * "application/vnd.vmware.vcloud.vm+xml" + */ + public final static String VM_XML = "application/vnd.vmware.vcloud.vm+xml"; + /** + * "application/vnd.vmware.vcloud.vm+xml" + */ + public final static MediaType VM_XML_TYPE = new MediaType("application", "vnd.vmware.vcloud.vm+xml"); + /** * "application/vnd.vmware.vcloud.vAppTemplate+xml" */ diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindDeployVAppParamsToXmlPayload.java b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindDeployVAppParamsToXmlPayload.java new file mode 100644 index 0000000000..7ae51fe337 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindDeployVAppParamsToXmlPayload.java @@ -0,0 +1,45 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.vcloud.binders; + +import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.rest.binders.BindToStringPayload; + +import com.google.inject.Inject; + +/** + * + * @author Adrian Cole + * + */ +@Singleton +public class BindDeployVAppParamsToXmlPayload extends BindParamsToXmlPayload { + + @Inject + public BindDeployVAppParamsToXmlPayload(BindToStringPayload stringBinder, + @Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns) { + super("DeployVAppParams", stringBinder, ns); + } + +} diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindParamsToXmlPayload.java b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindParamsToXmlPayload.java new file mode 100644 index 0000000000..69193227bd --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindParamsToXmlPayload.java @@ -0,0 +1,84 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.vcloud.binders; + +import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE; + +import java.util.Map; +import java.util.Properties; +import java.util.Map.Entry; + +import javax.inject.Named; +import javax.inject.Singleton; +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; + +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.MapBinder; +import org.jclouds.rest.binders.BindToStringPayload; + +import com.google.inject.Inject; +import com.jamesmurty.utils.XMLBuilder; + +/** + * + * @author Adrian Cole + * + */ +@Singleton +public class BindParamsToXmlPayload implements MapBinder { + + protected final String ns; + protected final BindToStringPayload stringBinder; + protected final String element; + + @Inject + public BindParamsToXmlPayload(String element, BindToStringPayload stringBinder, + @Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns) { + this.element = element; + this.ns = ns; + this.stringBinder = stringBinder; + } + + public void bindToRequest(HttpRequest request, Map postParams) { + try { + stringBinder.bindToRequest(request, generateXml(postParams)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private String generateXml(Map postParams) throws ParserConfigurationException, + FactoryConfigurationError, TransformerException { + XMLBuilder rootBuilder = XMLBuilder.create(element); + for (Entry entry : postParams.entrySet()) + rootBuilder.a(entry.getKey(), entry.getValue()); + rootBuilder.a("xmlns", ns); + Properties outputProperties = new Properties(); + outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes"); + return rootBuilder.asString(outputProperties); + } + + @Override + public void bindToRequest(HttpRequest request, Object input) { + throw new IllegalArgumentException("incorrect usage"); + } +} diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindUndeployVAppParamsToXmlPayload.java b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindUndeployVAppParamsToXmlPayload.java new file mode 100644 index 0000000000..3f7833c8d8 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/binders/BindUndeployVAppParamsToXmlPayload.java @@ -0,0 +1,45 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.vcloud.binders; + +import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_XML_NAMESPACE; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.rest.binders.BindToStringPayload; + +import com.google.inject.Inject; + +/** + * + * @author Adrian Cole + * + */ +@Singleton +public class BindUndeployVAppParamsToXmlPayload extends BindParamsToXmlPayload { + + @Inject + public BindUndeployVAppParamsToXmlPayload(BindToStringPayload stringBinder, + @Named(PROPERTY_VCLOUD_XML_NAMESPACE) String ns) { + super("UndeployVAppParams", stringBinder, ns); + } + +} diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/CommonVCloudComputeClient.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/CommonVCloudComputeClient.java index 656b25ad9d..0befb827c9 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/CommonVCloudComputeClient.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/CommonVCloudComputeClient.java @@ -46,7 +46,7 @@ public interface CommonVCloudComputeClient { * @param vAppId * vApp to reboot */ - void reboot(URI vAppId); + void reset(URI vAppId); /** * Destroys dependent resources, powers off and deletes the vApp, blocking until the following diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudComputeServiceContextModule.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudComputeServiceContextModule.java index ed3c4835fd..2692459c97 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudComputeServiceContextModule.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudComputeServiceContextModule.java @@ -31,13 +31,11 @@ import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.Size; import org.jclouds.compute.strategy.DestroyNodeStrategy; -import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy; import org.jclouds.domain.Location; import org.jclouds.vcloud.compute.internal.VCloudComputeClientImpl; import org.jclouds.vcloud.compute.strategy.VCloudDestroyNodeStrategy; -import org.jclouds.vcloud.compute.strategy.VCloudRebootNodeStrategy; import org.jclouds.vcloud.compute.suppliers.OrgAndVDCToLocationSupplier; import org.jclouds.vcloud.compute.suppliers.StaticSizeSupplier; import org.jclouds.vcloud.compute.suppliers.VCloudImageSupplier; @@ -78,7 +76,6 @@ public abstract class CommonVCloudComputeServiceContextModule extends BaseComput install(new ComputeServiceTimeoutsModule()); bind(DestroyNodeStrategy.class).to(VCloudDestroyNodeStrategy.class); bind(RunNodesAndAddToSetStrategy.class).to(EncodeTagIntoNameRunNodesAndAddToSetStrategy.class); - bind(RebootNodeStrategy.class).to(VCloudRebootNodeStrategy.class); bindLoadBalancer(); } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java index 598de01280..884611aa7a 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java @@ -27,6 +27,7 @@ import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.strategy.AddNodeWithTagStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.rest.RestContext; import org.jclouds.rest.internal.RestContextImpl; import org.jclouds.vcloud.VCloudClient; @@ -37,6 +38,7 @@ import org.jclouds.vcloud.compute.internal.VCloudComputeClientImpl; import org.jclouds.vcloud.compute.strategy.VCloudAddNodeWithTagStrategy; import org.jclouds.vcloud.compute.strategy.VCloudGetNodeMetadataStrategy; import org.jclouds.vcloud.compute.strategy.VCloudListNodesStrategy; +import org.jclouds.vcloud.compute.strategy.VCloudRebootNodeStrategy; import org.jclouds.vcloud.domain.Org; import com.google.common.base.Function; @@ -55,6 +57,7 @@ public class VCloudComputeServiceContextModule extends CommonVCloudComputeServic @Override protected void configure() { super.configure(); + bind(RebootNodeStrategy.class).to(VCloudRebootNodeStrategy.class); bind(GetNodeMetadataStrategy.class).to(VCloudGetNodeMetadataStrategy.class); bind(new TypeLiteral() { }).to(new TypeLiteral>() { diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressComputeServiceContextModule.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressComputeServiceContextModule.java index 2d7735878a..1e4d276d6d 100755 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressComputeServiceContextModule.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressComputeServiceContextModule.java @@ -27,6 +27,7 @@ import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.strategy.AddNodeWithTagStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.rest.RestContext; import org.jclouds.rest.internal.RestContextImpl; import org.jclouds.vcloud.VCloudExpressClient; @@ -37,6 +38,7 @@ import org.jclouds.vcloud.compute.internal.VCloudExpressComputeClientImpl; import org.jclouds.vcloud.compute.strategy.VCloudExpressAddNodeWithTagStrategy; import org.jclouds.vcloud.compute.strategy.VCloudExpressGetNodeMetadataStrategy; import org.jclouds.vcloud.compute.strategy.VCloudExpressListNodesStrategy; +import org.jclouds.vcloud.compute.strategy.VCloudExpressRebootNodeStrategy; import org.jclouds.vcloud.domain.Org; import com.google.common.base.Function; @@ -55,6 +57,7 @@ public class VCloudExpressComputeServiceContextModule extends CommonVCloudComput @Override protected void configure() { super.configure(); + bind(RebootNodeStrategy.class).to(VCloudExpressRebootNodeStrategy.class); bind(GetNodeMetadataStrategy.class).to(VCloudExpressGetNodeMetadataStrategy.class); bind(new TypeLiteral() { }).to(new TypeLiteral>() { diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/CommonVCloudComputeClientImpl.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/CommonVCloudComputeClientImpl.java index a14a4be243..b1a7a529d0 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/CommonVCloudComputeClientImpl.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/CommonVCloudComputeClientImpl.java @@ -76,16 +76,18 @@ public abstract class CommonVCloudComputeClientImpl } @Override - public void reboot(URI id) { + public void reset(URI id) { A vApp = refreshVApp(id); logger.debug(">> resetting vApp(%s)", vApp.getName()); - Task task = client.resetVApp(vApp.getId()); + Task task = reset(vApp); if (!taskTester.apply(task.getId())) { throw new RuntimeException(String.format("failed to %s %s: %s", "resetVApp", vApp.getName(), task)); } logger.debug("<< on vApp(%s)", vApp.getName()); } + protected abstract Task reset(A vApp); + protected abstract A refreshVApp(URI id); @Override @@ -105,7 +107,7 @@ public abstract class CommonVCloudComputeClientImpl private A undeployVAppIfDeployed(A vApp) { if (getStatus(vApp).compareTo(Status.RESOLVED) > 0) { logger.debug(">> undeploying vApp(%s), current status: %s", vApp.getName(), getStatus(vApp)); - Task task = client.undeployVApp(vApp.getId()); + Task task = undeploy(vApp); if (!taskTester.apply(task.getId())) { // TODO timeout throw new RuntimeException(String.format("failed to %s %s: %s", "undeploy", vApp.getName(), task)); @@ -116,10 +118,12 @@ public abstract class CommonVCloudComputeClientImpl return vApp; } + protected abstract Task undeploy(A vApp); + private A powerOffVAppIfDeployed(A vApp) { if (getStatus(vApp).compareTo(Status.OFF) > 0) { logger.debug(">> powering off vApp(%s), current status: %s", vApp.getName(), getStatus(vApp)); - Task task = client.powerOffVApp(vApp.getId()); + Task task = powerOff(vApp); if (!taskTester.apply(task.getId())) { // TODO timeout throw new RuntimeException(String.format("failed to %s %s: %s", "powerOff", vApp.getName(), task)); @@ -130,6 +134,8 @@ public abstract class CommonVCloudComputeClientImpl return vApp; } + protected abstract Task powerOff(A vApp); + protected abstract Status getStatus(A vApp); @Override diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/VCloudComputeClientImpl.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/VCloudComputeClientImpl.java index f27078fbdd..a6806c3cee 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/VCloudComputeClientImpl.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/internal/VCloudComputeClientImpl.java @@ -73,19 +73,13 @@ public class VCloudComputeClientImpl extends CommonVCloudComputeClientImpl> deploying vApp(%s)", vAppResponse.getName()); - Task task = client.deployVApp(vAppResponse.getId()); + Task task = VCloudClient.class.cast(client).deployAndPowerOnVAppOrVm(vAppResponse.getId()); if (options.shouldBlockOnDeploy()) { if (!taskTester.apply(task.getId())) { - throw new RuntimeException(String.format("failed to %s %s: %s", "deploy", vAppResponse.getName(), task)); + throw new RuntimeException(String.format("failed to %s %s: %s", "deploy and power on", vAppResponse + .getName(), task)); } - logger.debug("<< deployed vApp(%s)", vAppResponse.getName()); - - logger.debug(">> powering vApp(%s)", vAppResponse.getName()); - task = client.powerOnVApp(vAppResponse.getId()); - if (!taskTester.apply(task.getId())) { - throw new RuntimeException(String.format("failed to %s %s: %s", "powerOn", vAppResponse.getName(), task)); - } - logger.debug("<< on vApp(%s)", vAppResponse.getName()); + logger.debug("<< deployed and powered on vApp(%s)", vAppResponse.getName()); } return parseAndValidateResponse(template, vAppResponse); } @@ -112,4 +106,19 @@ public class VCloudComputeClientImpl extends CommonVCloudComputeClientImpl> deploying vApp(%s)", vAppResponse.getName()); - Task task = client.deployVApp(vAppResponse.getId()); + Task task = VCloudExpressClient.class.cast(client).deployVApp(vAppResponse.getId()); if (options.shouldBlockOnDeploy()) { if (!taskTester.apply(task.getId())) { throw new RuntimeException(String.format("failed to %s %s: %s", "deploy", vAppResponse.getName(), task)); @@ -83,7 +83,7 @@ public class VCloudExpressComputeClientImpl extends logger.debug("<< deployed vApp(%s)", vAppResponse.getName()); logger.debug(">> powering vApp(%s)", vAppResponse.getName()); - task = client.powerOnVApp(vAppResponse.getId()); + task = VCloudExpressClient.class.cast(client).powerOnVApp(vAppResponse.getId()); if (!taskTester.apply(task.getId())) { throw new RuntimeException(String.format("failed to %s %s: %s", "powerOn", vAppResponse.getName(), task)); } @@ -112,4 +112,19 @@ public class VCloudExpressComputeClientImpl extends protected VCloudExpressVApp refreshVApp(URI id) { return VCloudExpressClient.class.cast(client).getVApp(id); } + + @Override + protected Task powerOff(VCloudExpressVApp vApp) { + return VCloudExpressClient.class.cast(client).powerOffVApp(vApp.getId()); + } + + @Override + protected Task reset(VCloudExpressVApp vApp) { + return VCloudExpressClient.class.cast(client).resetVApp(vApp.getId()); + } + + @Override + protected Task undeploy(VCloudExpressVApp vApp) { + return VCloudExpressClient.class.cast(client).undeployVApp(vApp.getId()); + } } \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudExpressRebootNodeStrategy.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudExpressRebootNodeStrategy.java new file mode 100644 index 0000000000..4628cb50d9 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudExpressRebootNodeStrategy.java @@ -0,0 +1,61 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.vcloud.compute.strategy; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.strategy.GetNodeMetadataStrategy; +import org.jclouds.compute.strategy.RebootNodeStrategy; +import org.jclouds.vcloud.VCloudExpressClient; +import org.jclouds.vcloud.domain.Task; + +import com.google.common.base.Predicate; + +/** + * @author Adrian Cole + */ +@Singleton +public class VCloudExpressRebootNodeStrategy implements RebootNodeStrategy { + private final VCloudExpressClient client; + protected final Predicate taskTester; + protected final GetNodeMetadataStrategy getNode; + + @Inject + protected VCloudExpressRebootNodeStrategy(VCloudExpressClient client, Predicate taskTester, + GetNodeMetadataStrategy getNode) { + this.client = client; + this.taskTester = taskTester; + this.getNode = getNode; + } + + @Override + public NodeMetadata execute(String in) { + URI id = URI.create(checkNotNull(in, "node.id")); + Task task = client.resetVApp(id); + taskTester.apply(task.getId()); + return getNode.execute(in); + } +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudRebootNodeStrategy.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudRebootNodeStrategy.java index 0b022fe131..277da10632 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudRebootNodeStrategy.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudRebootNodeStrategy.java @@ -29,7 +29,7 @@ import javax.inject.Singleton; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; -import org.jclouds.vcloud.CommonVCloudClient; +import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.domain.Task; import com.google.common.base.Predicate; @@ -39,12 +39,12 @@ import com.google.common.base.Predicate; */ @Singleton public class VCloudRebootNodeStrategy implements RebootNodeStrategy { - private final CommonVCloudClient client; + private final VCloudClient client; protected final Predicate taskTester; protected final GetNodeMetadataStrategy getNode; @Inject - protected VCloudRebootNodeStrategy(CommonVCloudClient client, Predicate taskTester, + protected VCloudRebootNodeStrategy(VCloudClient client, Predicate taskTester, GetNodeMetadataStrategy getNode) { this.client = client; this.taskTester = taskTester; @@ -54,7 +54,7 @@ public class VCloudRebootNodeStrategy implements RebootNodeStrategy { @Override public NodeMetadata execute(String in) { URI id = URI.create(checkNotNull(in, "node.id")); - Task task = client.resetVApp(id); + Task task = client.resetVAppOrVm(id); taskTester.apply(task.getId()); return getNode.execute(in); } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/VApp.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/VApp.java index eed05164e5..eca568ffe1 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/VApp.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/VApp.java @@ -20,14 +20,16 @@ package org.jclouds.vcloud.domain; import java.util.List; +import java.util.Set; import javax.annotation.Nullable; /** - * A VApp is the result of instantiation of a {@link VAppTemplate}. - *

note

- *

When the {@link #getStatus} is {@link Status#UNRESOLVED}, there will be a task present for the instantiation of the VApp. - + * A VApp is the result of instantiation of a {@link VAppTemplate}.

note

+ *

+ * When the {@link #getStatus} is {@link Status#UNRESOLVED}, there will be a task present for the + * instantiation of the VApp. + * * @author Adrian Cole */ public interface VApp extends NamedResource { @@ -54,6 +56,13 @@ public interface VApp extends NamedResource { @Nullable String getDescription(); + /** + * + * @return true if the OVF descriptor for the template has been uploaded to the containing vDC. + * @since vcloud api 1.0 + */ + boolean isOvfDescriptorUploaded(); + /** * read‐only container for Task elements. Each element in the container represents a queued, * running, or failed task owned by this object. @@ -62,4 +71,11 @@ public interface VApp extends NamedResource { */ List getTasks(); + /** + * container for Vm elements representing virtual machines + * + * @since vcloud api 1.0 + */ + Set getChildren(); + } \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/VAppTemplate.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/VAppTemplate.java index 00cd03e43e..a720e2af4d 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/VAppTemplate.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/VAppTemplate.java @@ -20,27 +20,27 @@ package org.jclouds.vcloud.domain; import java.util.List; +import java.util.Set; import javax.annotation.Nullable; -import org.jclouds.vcloud.domain.internal.VDCImpl; +import org.jclouds.vcloud.domain.internal.VAppTemplateImpl; import com.google.inject.ImplementedBy; /** - * A VAppTemplate is an abstract description of a vApp. It is created when you - * upload an OVF package to a vDC. + * A VAppTemplate is an abstract description of a vApp. It is created when you upload an OVF package + * to a vDC. * * @author Adrian Cole */ -@ImplementedBy(VDCImpl.class) +@ImplementedBy(VAppTemplateImpl.class) public interface VAppTemplate extends NamedResource { /** * Reference to the VDC containing this template. * * @since vcloud api 1.0 - * @return org, or null if this is a version before 1.0 where the vdc isn't - * present + * @return org, or null if this is a version before 1.0 where the vdc isn't present */ NamedResource getVDC(); @@ -60,8 +60,8 @@ public interface VAppTemplate extends NamedResource { String getDescription(); /** - * read-only container for Task elements. Each element in the container - * represents a queued, running, or failed task owned by this object. + * read-only container for Task elements. Each element in the container represents a queued, + * running, or failed task owned by this object. * * @since vcloud api 1.0 */ @@ -69,8 +69,7 @@ public interface VAppTemplate extends NamedResource { /** * - * @return true if the OVF descriptor for the template has been uploaded to - * the containing vDC. + * @return true if the OVF descriptor for the template has been uploaded to the containing vDC. * @since vcloud api 1.0 */ boolean isOvfDescriptorUploaded(); @@ -83,4 +82,10 @@ public interface VAppTemplate extends NamedResource { @Nullable String getVAppScopedLocalId(); + /** + * container for Vm elements representing virtual machines + * + * @since vcloud api 1.0 + */ + Set getChildren(); } \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/Vm.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/Vm.java new file mode 100644 index 0000000000..25e6eb5e72 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/Vm.java @@ -0,0 +1,73 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.domain; + +import java.util.List; + +import javax.annotation.Nullable; + +/** + * A Vm represents a virtual machine, a member of a vApp’s Children container.

note

+ *

+ * When the {@link #getStatus} is {@link Status#UNRESOLVED}, there will be a task present for the + * instantiation of the VApp. + * + * @author Adrian Cole + */ +public interface Vm extends NamedResource { + /** + * Reference to the {@link VApp} or {@link VAppTemplate} containing this vm. + * + * @since vcloud api 1.0 + */ + NamedResource getParent(); + + /** + * @return creation status of the Vm or null, if a part of a VAppTemplate + * + * @since vcloud api 1.0 + */ + @Nullable + Status getStatus(); + + /** + * optional description + * + * @since vcloud api 0.8 + */ + @Nullable + String getDescription(); + + /** + * read‐only container for Task elements. Each element in the container represents a queued, + * running, or failed task owned by this object. + * + * @since vcloud api 1.0 + */ + List getTasks(); + + /** + * read-only identifier created on import + * + * @since vcloud api 1.0 + */ + @Nullable + String getVAppScopedLocalId(); +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VAppImpl.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VAppImpl.java index dd135b77f4..23b2b840a6 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VAppImpl.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VAppImpl.java @@ -7,7 +7,7 @@ * 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 + * http://www.apache.vdc/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, @@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.net.URI; import java.util.List; +import java.util.Set; import javax.annotation.Nullable; @@ -30,57 +31,93 @@ import org.jclouds.vcloud.domain.NamedResource; import org.jclouds.vcloud.domain.Status; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; +import org.jclouds.vcloud.domain.Vm; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; /** + * Locations of resources in vCloud * * @author Adrian Cole * */ public class VAppImpl extends NamedResourceImpl implements VApp { + private final Status status; - @Nullable private final NamedResource vdc; @Nullable private final String description; private final List tasks = Lists.newArrayList(); + private final boolean ovfDescriptorUploaded; + private final Set children = Sets.newLinkedHashSet(); - public VAppImpl(String name, String type, URI id, Status status, @Nullable NamedResource vdc, - @Nullable String description, Iterable tasks) { + public VAppImpl(String name, String type, URI id, Status status, NamedResource vdc, @Nullable String description, + Iterable tasks, boolean ovfDescriptorUploaded, Iterable children) { super(name, type, id); this.status = checkNotNull(status, "status"); - this.vdc = vdc; + this.vdc = vdc;// TODO: once <1.0 is killed check not null this.description = description; Iterables.addAll(this.tasks, checkNotNull(tasks, "tasks")); + this.ovfDescriptorUploaded = ovfDescriptorUploaded; + Iterables.addAll(this.children, checkNotNull(children, "children")); } + /** + * {@inheritDoc} + */ @Override public Status getStatus() { return status; } + /** + * {@inheritDoc} + */ @Override public NamedResource getVDC() { return vdc; } + /** + * {@inheritDoc} + */ @Override public String getDescription() { return description; } + /** + * {@inheritDoc} + */ @Override public List getTasks() { return tasks; } + /** + * {@inheritDoc} + */ + @Override + public boolean isOvfDescriptorUploaded() { + return ovfDescriptorUploaded; + } + + /** + * {@inheritDoc} + */ + @Override + public Set getChildren() { + return children; + } + @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + (ovfDescriptorUploaded ? 1231 : 1237); result = prime * result + ((status == null) ? 0 : status.hashCode()); result = prime * result + ((tasks == null) ? 0 : tasks.hashCode()); result = prime * result + ((vdc == null) ? 0 : vdc.hashCode()); @@ -101,6 +138,8 @@ public class VAppImpl extends NamedResourceImpl implements VApp { return false; } else if (!description.equals(other.description)) return false; + if (ovfDescriptorUploaded != other.ovfDescriptorUploaded) + return false; if (status == null) { if (other.status != null) return false; @@ -119,15 +158,10 @@ public class VAppImpl extends NamedResourceImpl implements VApp { return true; } - @Override - public int compareTo(NamedResource o) { - return (this == o) ? 0 : getId().compareTo(o.getId()); - } - @Override public String toString() { - return "[id=" + getId() + ", name=" + getName() + ", type=" + getType() + ", status=" + getStatus() + ", vdc=" - + getVDC() + ", description=" + getDescription() + "]"; + return "[id=" + getId() + ", name=" + getName() + ", vdc=" + vdc + ", description=" + description + ", status=" + + status + "]"; } } \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VAppTemplateImpl.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VAppTemplateImpl.java index de5e4c78d2..61ee0cb356 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VAppTemplateImpl.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VAppTemplateImpl.java @@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.net.URI; import java.util.List; +import java.util.Set; import javax.annotation.Nullable; @@ -30,9 +31,11 @@ import org.jclouds.vcloud.domain.NamedResource; import org.jclouds.vcloud.domain.Status; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VAppTemplate; +import org.jclouds.vcloud.domain.Vm; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; /** * Locations of resources in vCloud @@ -49,10 +52,11 @@ public class VAppTemplateImpl extends NamedResourceImpl implements VAppTemplate private final List tasks = Lists.newArrayList(); private final boolean ovfDescriptorUploaded; private final String vAppScopedLocalId; + private final Set children = Sets.newLinkedHashSet(); public VAppTemplateImpl(String name, String type, URI id, Status status, NamedResource vdc, - @Nullable String description, Iterable tasks, boolean ovfDescriptorUploaded, - @Nullable String vAppScopedLocalId) { + @Nullable String description, Iterable tasks, boolean ovfDescriptorUploaded, + @Nullable String vAppScopedLocalId, Iterable children) { super(name, type, id); this.status = checkNotNull(status, "status"); this.vdc = vdc;// TODO: once <1.0 is killed check not null @@ -60,6 +64,7 @@ public class VAppTemplateImpl extends NamedResourceImpl implements VAppTemplate Iterables.addAll(this.tasks, checkNotNull(tasks, "tasks")); this.vAppScopedLocalId = vAppScopedLocalId; this.ovfDescriptorUploaded = ovfDescriptorUploaded; + Iterables.addAll(this.children, checkNotNull(children, "children")); } /** @@ -110,6 +115,14 @@ public class VAppTemplateImpl extends NamedResourceImpl implements VAppTemplate return ovfDescriptorUploaded; } + /** + * {@inheritDoc} + */ + @Override + public Set getChildren() { + return children; + } + @Override public int hashCode() { final int prime = 31; @@ -165,7 +178,7 @@ public class VAppTemplateImpl extends NamedResourceImpl implements VAppTemplate @Override public String toString() { return "[id=" + getId() + ", name=" + getName() + ", vdc=" + vdc + ", description=" + description + ", status=" - + status + "]"; + + status + "]"; } } \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VmImpl.java b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VmImpl.java new file mode 100644 index 0000000000..eed6f93006 --- /dev/null +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/domain/internal/VmImpl.java @@ -0,0 +1,159 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vApp/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.domain.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; +import java.util.List; + +import javax.annotation.Nullable; + +import org.jclouds.vcloud.domain.NamedResource; +import org.jclouds.vcloud.domain.Status; +import org.jclouds.vcloud.domain.Task; +import org.jclouds.vcloud.domain.Vm; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; + +/** + * Locations of resources in vCloud + * + * @author Adrian Cole + * + */ +public class VmImpl extends NamedResourceImpl implements Vm { + + @Nullable + private final Status status; + private final NamedResource vApp; + @Nullable + private final String description; + private final List tasks = Lists.newArrayList(); + private final String vAppScopedLocalId; + + public VmImpl(String name, String type, URI id, @Nullable Status status, NamedResource vApp, + @Nullable String description, Iterable tasks, @Nullable String vAppScopedLocalId) { + super(name, type, id); + this.status = status; + this.vApp = vApp;// TODO: once <1.0 is killed check not null + this.description = description; + Iterables.addAll(this.tasks, checkNotNull(tasks, "tasks")); + this.vAppScopedLocalId = vAppScopedLocalId; + } + + /** + * {@inheritDoc} + */ + @Override + @Nullable + public Status getStatus() { + return status; + } + + /** + * {@inheritDoc} + */ + @Override + public NamedResource getParent() { + return vApp; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDescription() { + return description; + } + + /** + * {@inheritDoc} + */ + @Override + public List getTasks() { + return tasks; + } + + /** + * {@inheritDoc} + */ + @Override + public String getVAppScopedLocalId() { + return vAppScopedLocalId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + result = prime * result + ((tasks == null) ? 0 : tasks.hashCode()); + result = prime * result + ((vAppScopedLocalId == null) ? 0 : vAppScopedLocalId.hashCode()); + result = prime * result + ((vApp == null) ? 0 : vApp.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + VmImpl other = (VmImpl) obj; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (status == null) { + if (other.status != null) + return false; + } else if (!status.equals(other.status)) + return false; + if (tasks == null) { + if (other.tasks != null) + return false; + } else if (!tasks.equals(other.tasks)) + return false; + if (vAppScopedLocalId == null) { + if (other.vAppScopedLocalId != null) + return false; + } else if (!vAppScopedLocalId.equals(other.vAppScopedLocalId)) + return false; + if (vApp == null) { + if (other.vApp != null) + return false; + } else if (!vApp.equals(other.vApp)) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + getId() + ", name=" + getName() + ", vApp=" + vApp + ", description=" + description + ", status=" + + status + "]"; + } + +} \ No newline at end of file diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/xml/VAppHandler.java b/vcloud/core/src/main/java/org/jclouds/vcloud/xml/VAppHandler.java index 119f1f7268..c764d4ba2e 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/xml/VAppHandler.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/xml/VAppHandler.java @@ -19,71 +19,101 @@ package org.jclouds.vcloud.xml; -import static org.jclouds.Constants.PROPERTY_API_VERSION; +import static org.jclouds.vcloud.util.Utils.newNamedResource; import java.util.List; +import java.util.Set; import javax.inject.Inject; -import javax.inject.Named; import org.jclouds.http.functions.ParseSax; import org.jclouds.vcloud.domain.NamedResource; import org.jclouds.vcloud.domain.Status; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; +import org.jclouds.vcloud.domain.Vm; import org.jclouds.vcloud.domain.internal.VAppImpl; import org.jclouds.vcloud.util.Utils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; /** * @author Adrian Cole */ public class VAppHandler extends ParseSax.HandlerWithResult { - protected final String apiVersion; + protected final TaskHandler taskHandler; + protected final VmHandler vmHandler; @Inject - public VAppHandler(@Named(PROPERTY_API_VERSION) String apiVersion, TaskHandler taskHandler) { - this.apiVersion = apiVersion; + public VAppHandler(TaskHandler taskHandler, VmHandler vmHandler) { this.taskHandler = taskHandler; + this.vmHandler = vmHandler; } - private StringBuilder currentText = new StringBuilder(); + protected StringBuilder currentText = new StringBuilder(); - protected NamedResource vApp; - protected List tasks = Lists.newArrayList(); - protected String description; - protected NamedResource vdc; + protected NamedResource template; protected Status status; + protected NamedResource vdc; + protected String description; + protected List tasks = Lists.newArrayList(); + protected boolean ovfDescriptorUploaded = true; + + private boolean inChildren; + private boolean inTasks; + protected Set children = Sets.newLinkedHashSet(); public VApp getResult() { - return new VAppImpl(vApp.getName(), vApp.getType(), vApp.getId(), status, vdc, description, tasks); + return new VAppImpl(template.getName(), template.getType(), template.getId(), status, vdc, description, tasks, + ovfDescriptorUploaded, children); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { - if (qName.equals("VApp")) { - vApp = Utils.newNamedResource(attributes); - String statusString = attributes.getValue(attributes.getIndex("status")); - status = Status.fromValue(statusString); - // } else if (qName.equals("VAppItem")) { - // Utils.putNamedResource(contents, attributes); - } else if (qName.equals("Link") && "up".equals(Utils.attrOrNull(attributes, "rel"))) { - vdc = Utils.newNamedResource(attributes); - } else { - taskHandler.startElement(uri, localName, qName, attributes); + if (qName.equals("Children")) { + inChildren = true; + } else if (qName.equals("Tasks")) { + inTasks = true; } + if (inChildren) { + vmHandler.startElement(uri, localName, qName, attributes); + } else if (inTasks) { + taskHandler.startElement(uri, localName, qName, attributes); + } else if (qName.equals("VApp")) { + template = newNamedResource(attributes); + String status = Utils.attrOrNull(attributes, "status"); + if (status != null) + this.status = Status.fromValue(Integer.parseInt(status)); + } else if (qName.equals("Link") && "up".equals(Utils.attrOrNull(attributes, "rel")) && !inChildren) { + vdc = newNamedResource(attributes); + } + } public void endElement(String uri, String name, String qName) { - taskHandler.endElement(uri, name, qName); - if (qName.equals("Task")) { - this.tasks.add(taskHandler.getResult()); + if (qName.equals("Children")) { + inChildren = false; + } else if (qName.equals("Tasks")) { + inTasks = false; + } + if (inChildren) { + vmHandler.endElement(uri, name, qName); + if (qName.equals("Vm")) { + this.children.add(vmHandler.getResult()); + } + } else if (inTasks) { + taskHandler.endElement(uri, name, qName); + if (qName.equals("Task")) { + this.tasks.add(taskHandler.getResult()); + } } else if (qName.equals("Description")) { description = currentOrNull(); + } else if (qName.equals("ovfDescriptorUploaded")) { + ovfDescriptorUploaded = Boolean.parseBoolean(currentOrNull()); } currentText = new StringBuilder(); } diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/xml/VAppTemplateHandler.java b/vcloud/core/src/main/java/org/jclouds/vcloud/xml/VAppTemplateHandler.java index 1072b660d1..967f7d2881 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/xml/VAppTemplateHandler.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/xml/VAppTemplateHandler.java @@ -22,6 +22,7 @@ package org.jclouds.vcloud.xml; import static org.jclouds.vcloud.util.Utils.newNamedResource; import java.util.List; +import java.util.Set; import javax.inject.Inject; @@ -30,12 +31,14 @@ import org.jclouds.vcloud.domain.NamedResource; import org.jclouds.vcloud.domain.Status; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VAppTemplate; +import org.jclouds.vcloud.domain.Vm; import org.jclouds.vcloud.domain.internal.VAppTemplateImpl; import org.jclouds.vcloud.util.Utils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; /** * @author Adrian Cole @@ -43,10 +46,12 @@ import com.google.common.collect.Lists; public class VAppTemplateHandler extends ParseSax.HandlerWithResult { protected final TaskHandler taskHandler; + protected final VmHandler vmHandler; @Inject - public VAppTemplateHandler(TaskHandler taskHandler) { + public VAppTemplateHandler(TaskHandler taskHandler, VmHandler vmHandler) { this.taskHandler = taskHandler; + this.vmHandler = vmHandler; } protected StringBuilder currentText = new StringBuilder(); @@ -60,16 +65,25 @@ public class VAppTemplateHandler extends ParseSax.HandlerWithResult children = Sets.newLinkedHashSet(); public VAppTemplate getResult() { return new VAppTemplateImpl(template.getName(), template.getType(), template.getId(), status, vdc, description, - tasks, ovfDescriptorUploaded, vAppScopedLocalId); + tasks, ovfDescriptorUploaded, vAppScopedLocalId, children); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals("Children")) { inChildren = true; + } else if (qName.equals("Tasks")) { + inTasks = true; + } + if (inChildren) { + vmHandler.startElement(uri, localName, qName, attributes); + } else if (inTasks) { + taskHandler.startElement(uri, localName, qName, attributes); } else if (qName.equals("VAppTemplate")) { template = newNamedResource(attributes); String status = Utils.attrOrNull(attributes, "status"); @@ -77,19 +91,27 @@ public class VAppTemplateHandler extends ParseSax.HandlerWithResult + * + * ==================================================================== + * 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.vdc/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.xml; + +import static org.jclouds.vcloud.util.Utils.newNamedResource; + +import java.util.List; + +import javax.inject.Inject; + +import org.jclouds.http.functions.ParseSax; +import org.jclouds.vcloud.domain.NamedResource; +import org.jclouds.vcloud.domain.Status; +import org.jclouds.vcloud.domain.Task; +import org.jclouds.vcloud.domain.Vm; +import org.jclouds.vcloud.domain.internal.VmImpl; +import org.jclouds.vcloud.util.Utils; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +import com.google.common.collect.Lists; + +/** + * @author Adrian Cole + */ +public class VmHandler extends ParseSax.HandlerWithResult { + + protected final TaskHandler taskHandler; + + @Inject + public VmHandler(TaskHandler taskHandler) { + this.taskHandler = taskHandler; + } + + protected StringBuilder currentText = new StringBuilder(); + + protected NamedResource vm; + protected Status status; + protected NamedResource vdc; + protected String description; + protected List tasks = Lists.newArrayList(); + protected String vAppScopedLocalId; + + public Vm getResult() { + return new VmImpl(vm.getName(), vm.getType(), vm.getId(), status, vdc, description, tasks, vAppScopedLocalId); + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if (qName.equals("Vm")) { + vm = newNamedResource(attributes); + String status = Utils.attrOrNull(attributes, "status"); + if (status != null) + this.status = Status.fromValue(Integer.parseInt(status)); + } else if (qName.equals("Link") && "up".equals(Utils.attrOrNull(attributes, "rel"))) { + vdc = newNamedResource(attributes); + } else { + taskHandler.startElement(uri, localName, qName, attributes); + } + + } + + public void endElement(String uri, String name, String qName) { + taskHandler.endElement(uri, name, qName); + if (qName.equals("Task")) { + this.tasks.add(taskHandler.getResult()); + } else if (qName.equals("Description")) { + description = currentOrNull(); + } else if (qName.equals("VAppScopedLocalId")) { + vAppScopedLocalId = currentOrNull(); + } + currentText = new StringBuilder(); + } + + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } + + protected String currentOrNull() { + String returnVal = currentText.toString().trim(); + return returnVal.equals("") ? null : returnVal; + } +} diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java index 97fefc1233..0f4678bd00 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudAsyncClientTest.java @@ -92,16 +92,16 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testInstantiateVAppTemplateInVDCURI() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", URI.class, URI.class, - String.class, InstantiateVAppTemplateOptions[].class); + String.class, InstantiateVAppTemplateOptions[].class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"), "my-vapp"); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"), "my-vapp"); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/instantiateVAppTemplate HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/instantiateVAppTemplate HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n"); assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream("/newvapp.xml")), - "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false); + "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, VAppHandler.class); @@ -111,19 +111,20 @@ public class VCloudAsyncClientTest extends RestClientTest { } public void testInstantiateVAppTemplateInVDCURIOptions() throws SecurityException, NoSuchMethodException, - IOException { + IOException { Method method = VCloudAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", URI.class, URI.class, - String.class, InstantiateVAppTemplateOptions[].class); - HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"), "my-vapp", processorCount(1).memory( - 512).disk(1024).inNetwork(URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1990"))); + String.class, InstantiateVAppTemplateOptions[].class); + HttpRequest request = processor + .createRequest(method, URI.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/3"), "my-vapp", + processorCount(1).memory(512).disk(1024).inNetwork( + URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1990"))); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/instantiateVAppTemplate HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/instantiateVAppTemplate HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n"); assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream("/newvapp-cpumemdisk.xml")), - "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false); + "application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, VAppHandler.class); @@ -134,26 +135,26 @@ public class VCloudAsyncClientTest extends RestClientTest { @Test(expectedExceptions = IllegalArgumentException.class) public void testInstantiateVAppTemplateInOrgOptionsIllegalName() throws SecurityException, NoSuchMethodException, - IOException { + IOException { Method method = VCloudAsyncClient.class.getMethod("instantiateVAppTemplateInVDC", URI.class, URI.class, - String.class, InstantiateVAppTemplateOptions[].class); + String.class, InstantiateVAppTemplateOptions[].class); processor.createRequest(method, URI.create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), "CentOS 01", processorCount(1).memory(512) - .disk(1024).inNetwork(URI.create("https://vcenterprise.bluelock.com/network/1990"))); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), "CentOS 01", processorCount(1).memory(512) + .disk(1024).inNetwork(URI.create("https://vcenterprise.bluelock.com/network/1990"))); } public void testCloneVAppInVDC() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("cloneVAppInVDC", URI.class, URI.class, String.class, - CloneVAppOptions[].class); + CloneVAppOptions[].class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/4181"), "my-vapp"); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/4181"), "my-vapp"); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream("/cloneVApp-default.xml")), - "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); + "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -164,17 +165,17 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCloneVAppInVDCOptions() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("cloneVAppInVDC", URI.class, URI.class, String.class, - CloneVAppOptions[].class); + CloneVAppOptions[].class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/201"), "new-linux-server", new CloneVAppOptions() - .deploy().powerOn().withDescription("The description of the new vApp")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vapp/201"), "new-linux-server", + new CloneVAppOptions().deploy().powerOn().withDescription("The description of the new vApp")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vdc/1/action/cloneVApp HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, Utils.toStringAndClose(getClass().getResourceAsStream("/cloneVApp.xml")), - "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); + "application/vnd.vmware.vcloud.cloneVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -186,7 +187,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testOrg() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getOrg", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/org/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/org/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/org/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.org+xml\n"); @@ -217,7 +218,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCatalog() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getCatalog", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/catalog/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalog+xml\n"); @@ -248,7 +249,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testNetwork() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getNetwork", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/network/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/network/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/network/2 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.network+xml\n"); @@ -264,7 +265,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCatalogItemURI() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getCatalogItem", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.catalogItem+xml\n"); @@ -279,7 +280,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testFindCatalogItemInOrgCatalogNamed() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("findCatalogItemInOrgCatalogNamed", String.class, String.class, - String.class); + String.class); HttpRequest request = processor.createRequest(method, "org", "catalog", "item"); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1 HTTP/1.1"); @@ -295,7 +296,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testFindVAppTemplate() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("findVAppTemplateInOrgCatalogNamed", String.class, - String.class, String.class); + String.class, String.class); HttpRequest request = processor.createRequest(method, "org", "catalog", "template"); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2 HTTP/1.1"); @@ -312,7 +313,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testVAppTemplateURI() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVAppTemplate", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vAppTemplate+xml\n"); @@ -385,7 +386,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetVDC() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVDC", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vdc/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vdc+xml\n"); @@ -401,7 +402,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetTasksList() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getTasksList", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/tasksList/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.tasksList+xml\n"); @@ -429,14 +430,32 @@ public class VCloudAsyncClientTest extends RestClientTest { checkFilters(request); } - public void testDeployVApp() throws SecurityException, NoSuchMethodException, IOException { - Method method = VCloudAsyncClient.class.getMethod("deployVApp", URI.class); + public void testDeployVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("deployVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/deploy HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); - assertPayloadEquals(request, null, null, false); + assertPayloadEquals(request, "", + "application/vnd.vmware.vcloud.deployVAppParams+xml", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TaskHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testDeployAndPowerOnVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("deployAndPowerOnVAppOrVm", URI.class); + HttpRequest request = processor.createRequest(method, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + + assertRequestLineEquals(request, "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/deploy HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); + assertPayloadEquals(request, "", + "application/vnd.vmware.vcloud.deployVAppParams+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); @@ -448,7 +467,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetVApp() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getVApp", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vApp/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vApp+xml\n"); @@ -461,16 +480,54 @@ public class VCloudAsyncClientTest extends RestClientTest { checkFilters(request); } - public void testUndeployVApp() throws SecurityException, NoSuchMethodException, IOException { - Method method = VCloudAsyncClient.class.getMethod("undeployVApp", URI.class); + public void testRebootVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("rebootVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reboot HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); assertPayloadEquals(request, null, null, false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testUndeployVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("undeployVAppOrVm", URI.class); + HttpRequest request = processor.createRequest(method, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + + assertRequestLineEquals(request, + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); + assertPayloadEquals(request, "", + "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TaskHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testUndeployAndSaveStateOfVAppOrVmSaveState() throws SecurityException, NoSuchMethodException, + IOException { + Method method = VCloudAsyncClient.class.getMethod("undeployAndSaveStateOfVAppOrVm", URI.class); + HttpRequest request = processor.createRequest(method, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + + assertRequestLineEquals(request, + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/action/undeploy HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); + assertPayloadEquals(request, + "", + "application/vnd.vmware.vcloud.undeployVAppParams+xml", false); + assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, TaskHandler.class); assertExceptionParserClassEquals(method, null); @@ -481,7 +538,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testDeleteVApp() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("deleteVApp", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, "DELETE https://vcenterprise.bluelock.com/api/v1.0/vApp/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); @@ -494,13 +551,13 @@ public class VCloudAsyncClientTest extends RestClientTest { checkFilters(request); } - public void testPowerOn() throws SecurityException, NoSuchMethodException, IOException { - Method method = VCloudAsyncClient.class.getMethod("powerOnVApp", URI.class); + public void testPowerOnVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("powerOnVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOn HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOn HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -511,13 +568,13 @@ public class VCloudAsyncClientTest extends RestClientTest { checkFilters(request); } - public void testPowerOff() throws SecurityException, NoSuchMethodException, IOException { - Method method = VCloudAsyncClient.class.getMethod("powerOffVApp", URI.class); + public void testPowerOffVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("powerOffVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOff HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/powerOff HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -528,13 +585,13 @@ public class VCloudAsyncClientTest extends RestClientTest { checkFilters(request); } - public void testReset() throws SecurityException, NoSuchMethodException, IOException { - Method method = VCloudAsyncClient.class.getMethod("resetVApp", URI.class); + public void testResetVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("resetVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reset HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/reset HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -545,13 +602,13 @@ public class VCloudAsyncClientTest extends RestClientTest { checkFilters(request); } - public void testSuspend() throws SecurityException, NoSuchMethodException, IOException { - Method method = VCloudAsyncClient.class.getMethod("suspendVApp", URI.class); + public void testSuspendVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("suspendVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/suspend HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/suspend HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); assertPayloadEquals(request, null, null, false); @@ -562,13 +619,13 @@ public class VCloudAsyncClientTest extends RestClientTest { checkFilters(request); } - public void testShutdown() throws SecurityException, NoSuchMethodException, IOException { - Method method = VCloudAsyncClient.class.getMethod("shutdownVApp", URI.class); + public void testShutdownVAppOrVm() throws SecurityException, NoSuchMethodException, IOException { + Method method = VCloudAsyncClient.class.getMethod("shutdownVAppOrVm", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/1")); assertRequestLineEquals(request, - "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/shutdown HTTP/1.1"); + "POST https://vcenterprise.bluelock.com/api/v1.0/vApp/1/power/action/shutdown HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); assertPayloadEquals(request, null, null, false); @@ -582,7 +639,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testGetTask() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("getTask", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/task/1 HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.task+xml\n"); @@ -598,7 +655,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public void testCancelTask() throws SecurityException, NoSuchMethodException, IOException { Method method = VCloudAsyncClient.class.getMethod("cancelTask", URI.class); HttpRequest request = processor.createRequest(method, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); + .create("https://vcenterprise.bluelock.com/api/v1.0/task/1")); assertRequestLineEquals(request, "POST https://vcenterprise.bluelock.com/api/v1.0/task/1/action/cancel HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); @@ -640,7 +697,7 @@ public class VCloudAsyncClientTest extends RestClientTest { public static class VCloudRestClientModuleExtension extends VCloudRestClientModule { @Override protected URI provideAuthenticationURI(VCloudVersionsAsyncClient versionService, - @Named(PROPERTY_API_VERSION) String version) { + @Named(PROPERTY_API_VERSION) String version) { return URI.create("https://vcenterprise.bluelock.com/api/v1.0/login"); } @@ -683,13 +740,13 @@ public class VCloudAsyncClientTest extends RestClientTest { @Override protected Supplier provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, - final VCloudLoginAsyncClient login) { + final VCloudLoginAsyncClient login) { return Suppliers. ofInstance(new VCloudSession() { @Override public Map getOrgs() { return ImmutableMap. of("org", new NamedResourceImpl("org", - VCloudMediaType.ORG_XML, URI.create("https://vcenterprise.bluelock.com/api/v1.0/org/1"))); + VCloudMediaType.ORG_XML, URI.create("https://vcenterprise.bluelock.com/api/v1.0/org/1"))); } @Override @@ -710,19 +767,44 @@ public class VCloudAsyncClientTest extends RestClientTest { } protected Supplier>> provideOrgVDCSupplierCache( - @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { + @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { - return Suppliers.>> ofInstance(ImmutableMap - .> of("org", + return Suppliers + .>> ofInstance(ImmutableMap + .> of( + "org", - ImmutableMap. of("vdc", new VDCImpl("vdc", null, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), null, null, "description", null, - null, null, null, null, ImmutableMap. of("vapp", new NamedResourceImpl( - "vapp", "application/vnd.vmware.vcloud.vApp+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/188849-1")), "network", - new NamedResourceImpl("network", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdcItem/2"))), null, 0, 0, 0, - false)))); + ImmutableMap + . of( + "vdc", + new VDCImpl( + "vdc", + null, + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"), + null, + null, + "description", + null, + null, + null, + null, + null, + ImmutableMap + . of( + "vapp", + new NamedResourceImpl( + "vapp", + "application/vnd.vmware.vcloud.vApp+xml", + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/188849-1")), + "network", + new NamedResourceImpl( + "network", + "application/vnd.vmware.vcloud.vAppTemplate+xml", + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdcItem/2"))), + null, 0, 0, 0, false)))); } @@ -736,15 +818,18 @@ public class VCloudAsyncClientTest extends RestClientTest { @Override public Map get() { return ImmutableMap. of("org", new OrgImpl("org", null, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/org/1"), "org", "description", ImmutableMap - . of("catalog", new NamedResourceImpl("catalog", VCloudMediaType.CATALOG_XML, - URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"))), ImmutableMap - . of("vdc", new NamedResourceImpl("vdc", VCloudMediaType.VDC_XML, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"))), ImmutableMap - . of("network", new NamedResourceImpl("network", VCloudMediaType.NETWORK_XML, - URI.create("https://vcenterprise.bluelock.com/api/v1.0/network/1"))), new NamedResourceImpl( - "tasksList", VCloudMediaType.TASKSLIST_XML, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")), ImmutableList. of())); + .create("https://vcenterprise.bluelock.com/api/v1.0/org/1"), "org", "description", ImmutableMap + . of("catalog", new NamedResourceImpl("catalog", + VCloudMediaType.CATALOG_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"))), ImmutableMap + . of("vdc", new NamedResourceImpl("vdc", VCloudMediaType.VDC_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1"))), ImmutableMap + . of("network", new NamedResourceImpl("network", + VCloudMediaType.NETWORK_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/network/1"))), + new NamedResourceImpl("tasksList", VCloudMediaType.TASKSLIST_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/tasksList/1")), ImmutableList + . of())); } } @@ -760,13 +845,14 @@ public class VCloudAsyncClientTest extends RestClientTest { return ImmutableMap.> of("org", ImmutableMap. of("catalog", new CatalogImpl("catalog", "type", - URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"), null, "description", ImmutableMap - . of("item", new NamedResourceImpl("item", + URI.create("https://vcenterprise.bluelock.com/api/v1.0/catalog/1"), null, "description", + ImmutableMap. of("item", new NamedResourceImpl("item", "application/vnd.vmware.vcloud.catalogItem+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1")), "template", - new NamedResourceImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"))), - ImmutableList. of(), true))); + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/1")), + "template", new NamedResourceImpl("template", + "application/vnd.vmware.vcloud.vAppTemplate+xml", URI + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"))), + ImmutableList. of(), true))); } } @@ -778,14 +864,26 @@ public class VCloudAsyncClientTest extends RestClientTest { @Override public Map>> get() { - return ImmutableMap.>> of( - "org", ImmutableMap.> of( - "catalog", ImmutableMap. of("template", - new CatalogItemImpl("template", URI - .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"), "description", - new NamedResourceImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml", - URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")), - ImmutableMap. of())))); + return ImmutableMap + .>> of( + "org", + ImmutableMap + .> of( + "catalog", + ImmutableMap + . of( + "template", + new CatalogItemImpl( + "template", + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/catalogItem/2"), + "description", + new NamedResourceImpl( + "template", + "application/vnd.vmware.vcloud.vAppTemplate+xml", + URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/2")), + ImmutableMap. of())))); } } diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java index 8f6a1c251a..535a9c19f0 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudClientLiveTest.java @@ -83,6 +83,25 @@ public class VCloudClientLiveTest extends CommonVCloudClientLiveTest + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.vcloud.binders; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.Properties; + +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.vcloud.VCloudPropertiesBuilder; +import org.testng.annotations.Test; + +import com.google.common.collect.Maps; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.name.Names; + +/** + * Tests behavior of {@code BindDeployVAppParamsToXmlPayload} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "vcloud.BindDeployVAppParamsToXmlPayloadTest") +public class BindDeployVAppParamsToXmlPayloadTest { + Injector injector = Guice.createInjector(new AbstractModule() { + + @Override + protected void configure() { + Properties props = new Properties(); + Names.bindProperties(binder(), checkNotNull(new VCloudPropertiesBuilder(props).build(), "properties")); + } + }); + + public void testPowerOnTrue() throws IOException { + String expected = ""; + + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); + expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); + request.setPayload(expected); + replay(request); + + BindDeployVAppParamsToXmlPayload binder = injector.getInstance(BindDeployVAppParamsToXmlPayload.class); + + Map map = Maps.newHashMap(); + map.put("powerOn", "true"); + binder.bindToRequest(request, map); + verify(request); + } + + public void testDefault() throws IOException { + String expected = ""; + + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); + expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); + request.setPayload(expected); + replay(request); + + BindDeployVAppParamsToXmlPayload binder = injector.getInstance(BindDeployVAppParamsToXmlPayload.class); + + Map map = Maps.newHashMap(); + + binder.bindToRequest(request, map); + verify(request); + } +} diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/binders/BindUndeployVAppParamsToXmlPayloadTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/binders/BindUndeployVAppParamsToXmlPayloadTest.java new file mode 100644 index 0000000000..cc36773e8e --- /dev/null +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/binders/BindUndeployVAppParamsToXmlPayloadTest.java @@ -0,0 +1,90 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.vcloud.binders; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.Properties; + +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.vcloud.VCloudPropertiesBuilder; +import org.testng.annotations.Test; + +import com.google.common.collect.Maps; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.name.Names; + +/** + * Tests behavior of {@code BindUndeployVAppParamsToXmlPayload} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "vcloud.BindUndeployVAppParamsToXmlPayloadTest") +public class BindUndeployVAppParamsToXmlPayloadTest { + Injector injector = Guice.createInjector(new AbstractModule() { + + @Override + protected void configure() { + Properties props = new Properties(); + Names.bindProperties(binder(), checkNotNull(new VCloudPropertiesBuilder(props).build(), "properties")); + } + }); + + public void testSaveStateTrue() throws IOException { + String expected = ""; + + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); + expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); + request.setPayload(expected); + replay(request); + + BindUndeployVAppParamsToXmlPayload binder = injector.getInstance(BindUndeployVAppParamsToXmlPayload.class); + + Map map = Maps.newHashMap(); + map.put("saveState", "true"); + binder.bindToRequest(request, map); + verify(request); + } + + public void testDefault() throws IOException { + String expected = ""; + + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); + expect(request.getEndpoint()).andReturn(URI.create("http://localhost/key")).anyTimes(); + request.setPayload(expected); + replay(request); + + BindUndeployVAppParamsToXmlPayload binder = injector.getInstance(BindUndeployVAppParamsToXmlPayload.class); + + Map map = Maps.newHashMap(); + + binder.bindToRequest(request, map); + verify(request); + } +} diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VAppHandlerTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VAppHandlerTest.java new file mode 100644 index 0000000000..a6d216e0fc --- /dev/null +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VAppHandlerTest.java @@ -0,0 +1,76 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.xml; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; +import java.net.URI; + +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ParseSax.Factory; +import org.jclouds.http.functions.config.SaxParserModule; +import org.jclouds.vcloud.VCloudMediaType; +import org.jclouds.vcloud.domain.Status; +import org.jclouds.vcloud.domain.VApp; +import org.jclouds.vcloud.domain.Vm; +import org.jclouds.vcloud.domain.internal.NamedResourceImpl; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * Tests behavior of {@code VAppHandler} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "vcloud.VAppHandlerTest") +public class VAppHandlerTest { + public void testRhelOffStatic() { + InputStream is = getClass().getResourceAsStream("/vapp-rhel-off-static.xml"); + Injector injector = Guice.createInjector(new SaxParserModule()); + Factory factory = injector.getInstance(ParseSax.Factory.class); + VApp result = factory.create(injector.getInstance(VAppHandler.class)).parse(is); + assertEquals(result.getName(), "vApp_acole_2"); + assertEquals(result.getId(), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vapp-607806320")); + assertEquals(result.getType(), "application/vnd.vmware.vcloud.vApp+xml"); + assertEquals(result.getStatus(), Status.OFF); + assertEquals(result.getVDC(), new NamedResourceImpl(null, VCloudMediaType.VDC_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1014839439"))); + assertEquals(result.getDescription(), null); + assertEquals(result.getTasks(), ImmutableList.of()); + assert result.isOvfDescriptorUploaded(); + Vm vm = Iterables.getOnlyElement(result.getChildren()); + assertEquals(vm.getName(), "RHEL5"); + assertEquals(vm.getId(), URI.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vm-2087535248")); + assertEquals(vm.getType(), "application/vnd.vmware.vcloud.vm+xml"); + assertEquals(vm.getStatus(), Status.OFF); + assertEquals(vm.getParent(), new NamedResourceImpl(null, VCloudMediaType.VAPP_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vapp-607806320"))); + assertEquals(vm.getDescription(), null); + assertEquals(vm.getTasks(), ImmutableList.of()); + assertEquals(vm.getVAppScopedLocalId(), null); + } + +} diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VAppTemplateHandlerTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VAppTemplateHandlerTest.java index 557c7c4208..4118939021 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VAppTemplateHandlerTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VAppTemplateHandlerTest.java @@ -30,10 +30,12 @@ import org.jclouds.http.functions.config.SaxParserModule; import org.jclouds.vcloud.VCloudMediaType; import org.jclouds.vcloud.domain.Status; import org.jclouds.vcloud.domain.VAppTemplate; +import org.jclouds.vcloud.domain.Vm; import org.jclouds.vcloud.domain.internal.NamedResourceImpl; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import com.google.inject.Guice; import com.google.inject.Injector; @@ -44,21 +46,33 @@ import com.google.inject.Injector; */ @Test(groups = "unit", testName = "vcloud.VAppTemplateHandlerTest") public class VAppTemplateHandlerTest { - public void testVCloud1_0() { + public void testUbuntuTemplate() { InputStream is = getClass().getResourceAsStream("/vAppTemplate.xml"); Injector injector = Guice.createInjector(new SaxParserModule()); Factory factory = injector.getInstance(ParseSax.Factory.class); VAppTemplate result = factory.create(injector.getInstance(VAppTemplateHandler.class)).parse(is); assertEquals(result.getName(), "Ubuntu Template"); - assertEquals(result.getId(), URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/vappTemplate-1201908921")); + assertEquals(result.getId(), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/vappTemplate-1201908921")); assertEquals(result.getType(), "application/vnd.vmware.vcloud.vAppTemplate+xml"); assertEquals(result.getStatus(), Status.OFF); assertEquals(result.getVDC(), new NamedResourceImpl(null, VCloudMediaType.VDC_XML, URI - .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1014839439"))); + .create("https://vcenterprise.bluelock.com/api/v1.0/vdc/1014839439"))); assertEquals(result.getDescription(), null); assertEquals(result.getTasks(), ImmutableList.of()); - assertEquals(result.getVAppScopedLocalId(), "02_ubuntu_template"); + assertEquals(result.getVAppScopedLocalId(), null); assert result.isOvfDescriptorUploaded(); + Vm vm = Iterables.getOnlyElement(result.getChildren()); + assertEquals(vm.getName(), "Ubuntu1004"); + assertEquals(vm.getId(), URI.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/vm-172837194")); + // NOTE this is vAppTemplate not VM! + assertEquals(vm.getType(), "application/vnd.vmware.vcloud.vAppTemplate+xml"); + assertEquals(vm.getStatus(), null); + assertEquals(vm.getParent(), new NamedResourceImpl(null, VCloudMediaType.VAPPTEMPLATE_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/vappTemplate-1201908921"))); + assertEquals(vm.getDescription(), null); + assertEquals(vm.getTasks(), ImmutableList.of()); + assertEquals(vm.getVAppScopedLocalId(), null); } } diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VmHandlerTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VmHandlerTest.java new file mode 100644 index 0000000000..58a27d26bf --- /dev/null +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/xml/VmHandlerTest.java @@ -0,0 +1,64 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.xml; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; +import java.net.URI; + +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ParseSax.Factory; +import org.jclouds.http.functions.config.SaxParserModule; +import org.jclouds.vcloud.VCloudMediaType; +import org.jclouds.vcloud.domain.Status; +import org.jclouds.vcloud.domain.Vm; +import org.jclouds.vcloud.domain.internal.NamedResourceImpl; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * Tests behavior of {@code VmHandler} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "vcloud.VmHandlerTest") +public class VmHandlerTest { + public void testVCloud1_0() { + InputStream is = getClass().getResourceAsStream("/vm-rhel-off-static.xml"); + Injector injector = Guice.createInjector(new SaxParserModule()); + Factory factory = injector.getInstance(ParseSax.Factory.class); + Vm result = factory.create(injector.getInstance(VmHandler.class)).parse(is); + assertEquals(result.getName(), "RHEL5"); + assertEquals(result.getId(), URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vm-2087535248")); + assertEquals(result.getType(), "application/vnd.vmware.vcloud.vm+xml"); + assertEquals(result.getStatus(), Status.OFF); + assertEquals(result.getParent(), new NamedResourceImpl(null, VCloudMediaType.VAPP_XML, URI + .create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vapp-607806320"))); + assertEquals(result.getDescription(), null); + assertEquals(result.getTasks(), ImmutableList.of()); + assertEquals(result.getVAppScopedLocalId(), "10_rhel_template"); + } + +} diff --git a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkVCloudComputeServiceContextModule.java b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkVCloudComputeServiceContextModule.java index a1de4a687d..f336d590f2 100755 --- a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkVCloudComputeServiceContextModule.java +++ b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkVCloudComputeServiceContextModule.java @@ -47,7 +47,7 @@ import org.jclouds.vcloud.compute.VCloudExpressComputeClient; import org.jclouds.vcloud.compute.config.VCloudExpressComputeServiceContextModule; import org.jclouds.vcloud.compute.strategy.VCloudDestroyNodeStrategy; import org.jclouds.vcloud.compute.strategy.VCloudExpressListNodesStrategy; -import org.jclouds.vcloud.compute.strategy.VCloudRebootNodeStrategy; +import org.jclouds.vcloud.compute.strategy.VCloudExpressRebootNodeStrategy; import org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeClient; import org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeService; import org.jclouds.vcloud.terremark.compute.domain.KeyPairCredentials; @@ -100,7 +100,7 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudExpressCom bind(ListNodesStrategy.class).to(VCloudExpressListNodesStrategy.class); // NOTE bind(GetNodeMetadataStrategy.class).to(TerremarkVCloudGetNodeMetadataStrategy.class); - bind(RebootNodeStrategy.class).to(VCloudRebootNodeStrategy.class); + bind(RebootNodeStrategy.class).to(VCloudExpressRebootNodeStrategy.class); bind(DestroyNodeStrategy.class).to(VCloudDestroyNodeStrategy.class); bindLoadBalancer(); // MORE specifics...