Issue 280: corrected xml handlers and added getVm command

This commit is contained in:
Adrian Cole 2010-08-24 13:03:09 -07:00
parent c6d046494e
commit 1cfd0b051b
15 changed files with 88 additions and 70 deletions

View File

@ -24,6 +24,7 @@ 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;
import static org.jclouds.vcloud.VCloudMediaType.VM_XML;
import java.net.URI;
@ -51,6 +52,7 @@ import org.jclouds.vcloud.binders.BindUndeployVAppParamsToXmlPayload;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.domain.Vm;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.functions.OrgNameCatalogNameVAppTemplateNameToEndpoint;
import org.jclouds.vcloud.functions.OrgNameVDCNameResourceEntityNameToEndpoint;
@ -59,6 +61,7 @@ import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
import org.jclouds.vcloud.xml.TaskHandler;
import org.jclouds.vcloud.xml.VAppHandler;
import org.jclouds.vcloud.xml.VAppTemplateHandler;
import org.jclouds.vcloud.xml.VmHandler;
import com.google.common.util.concurrent.ListenableFuture;
@ -142,6 +145,15 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends VApp> getVApp(@EndpointParam URI vApp);
/**
* @see VCloudClient#getVm
*/
@GET
@Consumes(VM_XML)
@XMLResponseParser(VmHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<? extends Vm> getVm(@EndpointParam URI vm);
/**
* @see VCloudClient#deployVAppOrVm
*/

View File

@ -29,6 +29,7 @@ import org.jclouds.concurrent.Timeout;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.domain.Vm;
import org.jclouds.vcloud.options.CloneVAppOptions;
import org.jclouds.vcloud.options.InstantiateVAppTemplateOptions;
@ -69,6 +70,8 @@ public interface VCloudClient extends CommonVCloudClient {
VApp getVApp(URI vApp);
Vm getVm(URI vm);
/**
* 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,

View File

@ -23,6 +23,10 @@ import java.util.List;
import javax.annotation.Nullable;
import org.jclouds.vcloud.domain.internal.VmImpl;
import com.google.inject.ImplementedBy;
/**
* A Vm represents a virtual machine, a member of a vApps Children container. <h2>note</h2>
* <p/>
@ -31,6 +35,7 @@ import javax.annotation.Nullable;
*
* @author Adrian Cole
*/
@ImplementedBy(VmImpl.class)
public interface Vm extends ReferenceType {
/**
* Reference to the {@link VApp} or {@link VAppTemplate} containing this vm.

View File

@ -140,16 +140,6 @@ public class VAppImpl extends ReferenceTypeImpl implements VApp {
return false;
if (ovfDescriptorUploaded != other.ovfDescriptorUploaded)
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 (vdc == null) {
if (other.vdc != null)
return false;

View File

@ -152,16 +152,6 @@ public class VAppTemplateImpl extends ReferenceTypeImpl implements VAppTemplate
return false;
if (ovfDescriptorUploaded != other.ovfDescriptorUploaded)
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;

View File

@ -108,8 +108,8 @@ public class VmImpl extends ReferenceTypeImpl implements Vm {
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());
result = prime * result + ((vAppScopedLocalId == null) ? 0 : vAppScopedLocalId.hashCode());
return result;
}
@ -127,33 +127,24 @@ public class VmImpl extends ReferenceTypeImpl implements Vm {
return false;
} else if (!description.equals(other.description))
return false;
if (status == null) {
if (other.status != null)
if (vApp == null) {
if (other.vApp != 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))
} else if (!vApp.equals(other.vApp))
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=" + getHref() + ", name=" + getName() + ", vApp=" + vApp + ", description=" + description + ", status="
+ status + "]";
return "[href=" + getHref() + ", name=" + getName() + ", type=" + getType() + ", description=" + description
+ ", status=" + status + ", tasks=" + tasks + ", vApp=" + vApp + ", vAppScopedLocalId="
+ vAppScopedLocalId + "]";
}
}

View File

@ -76,7 +76,7 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("Children")) {
inChildren = true;
} else if (qName.equals("Tasks")) {
} else if (!inChildren && qName.equals("Tasks")) {
inTasks = true;
}
if (inChildren) {
@ -88,7 +88,7 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
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) {
} else if (qName.equals("Link") && "up".equals(Utils.attrOrNull(attributes, "rel"))) {
vdc = newNamedResource(attributes);
}
@ -97,7 +97,7 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
public void endElement(String uri, String name, String qName) {
if (qName.equals("Children")) {
inChildren = false;
} else if (qName.equals("Tasks")) {
} else if (!inChildren && qName.equals("Tasks")) {
inTasks = false;
}
if (inChildren) {
@ -120,6 +120,7 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
vmHandler.characters(ch, start, length);
}
protected String currentOrNull() {

View File

@ -77,7 +77,7 @@ public class VAppTemplateHandler extends ParseSax.HandlerWithResult<VAppTemplate
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("Children")) {
inChildren = true;
} else if (qName.equals("Tasks")) {
} else if (!inChildren && qName.equals("Tasks")) {
inTasks = true;
}
if (inChildren) {
@ -89,7 +89,7 @@ public class VAppTemplateHandler extends ParseSax.HandlerWithResult<VAppTemplate
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) {
} else if (qName.equals("Link") && "up".equals(Utils.attrOrNull(attributes, "rel"))) {
vdc = newNamedResource(attributes);
}
@ -98,7 +98,7 @@ public class VAppTemplateHandler extends ParseSax.HandlerWithResult<VAppTemplate
public void endElement(String uri, String name, String qName) {
if (qName.equals("Children")) {
inChildren = false;
} else if (qName.equals("Tasks")) {
} else if (!inChildren && qName.equals("Tasks")) {
inTasks = false;
}
if (inChildren) {
@ -123,6 +123,7 @@ public class VAppTemplateHandler extends ParseSax.HandlerWithResult<VAppTemplate
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
vmHandler.characters(ch, start, length);
}
protected String currentOrNull() {

View File

@ -58,29 +58,38 @@ public class VmHandler extends ParseSax.HandlerWithResult<Vm> {
protected List<Task> tasks = Lists.newArrayList();
protected String vAppScopedLocalId;
private boolean inTasks;
public Vm getResult() {
return new VmImpl(vm.getName(), vm.getType(), vm.getHref(), status, vdc, description, tasks, vAppScopedLocalId);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("Vm")) {
if (qName.equals("Tasks")) {
inTasks = true;
}
if (inTasks) {
taskHandler.startElement(uri, localName, qName, attributes);
} else 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) {
if (qName.equals("Tasks")) {
inTasks = false;
}
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("VAppScopedLocalId")) {

View File

@ -49,14 +49,14 @@ import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.util.Utils;
import org.jclouds.vcloud.config.VCloudRestClientModule;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Org;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VCloudSession;
import org.jclouds.vcloud.domain.internal.CatalogImpl;
import org.jclouds.vcloud.domain.internal.CatalogItemImpl;
import org.jclouds.vcloud.domain.internal.ReferenceTypeImpl;
import org.jclouds.vcloud.domain.internal.OrgImpl;
import org.jclouds.vcloud.domain.internal.ReferenceTypeImpl;
import org.jclouds.vcloud.domain.internal.VDCImpl;
import org.jclouds.vcloud.filters.SetVCloudTokenCookie;
import org.jclouds.vcloud.options.CloneVAppOptions;
@ -70,6 +70,7 @@ import org.jclouds.vcloud.xml.TasksListHandler;
import org.jclouds.vcloud.xml.VAppHandler;
import org.jclouds.vcloud.xml.VAppTemplateHandler;
import org.jclouds.vcloud.xml.VDCHandler;
import org.jclouds.vcloud.xml.VmHandler;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
@ -480,6 +481,22 @@ public class VCloudAsyncClientTest extends RestClientTest<VCloudAsyncClient> {
checkFilters(request);
}
public void testGetVm() throws SecurityException, NoSuchMethodException, IOException {
Method method = VCloudAsyncClient.class.getMethod("getVm", URI.class);
HttpRequest request = processor.createRequest(method, URI
.create("https://vcenterprise.bluelock.com/api/v1.0/vm/1"));
assertRequestLineEquals(request, "GET https://vcenterprise.bluelock.com/api/v1.0/vm/1 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/vnd.vmware.vcloud.vm+xml\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VmHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
}
public void testRebootVAppOrVm() throws SecurityException, NoSuchMethodException, IOException {
Method method = VCloudAsyncClient.class.getMethod("rebootVAppOrVm", URI.class);
HttpRequest request = processor.createRequest(method, URI

View File

@ -20,15 +20,17 @@
package org.jclouds.vcloud;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.Org;
import org.jclouds.vcloud.domain.ReferenceType;
import org.jclouds.vcloud.domain.VApp;
import org.jclouds.vcloud.domain.VDC;
import org.jclouds.vcloud.domain.Vm;
import org.testng.annotations.Test;
/**
@ -83,7 +85,6 @@ public class VCloudClientLiveTest extends CommonVCloudClientLiveTest<VCloudClien
}
}
@Test
public void testGetVm() throws Exception {
Org org = connection.findOrgNamed(null);
@ -94,6 +95,9 @@ public class VCloudClientLiveTest extends CommonVCloudClientLiveTest<VCloudClien
try {
VApp app = connection.getVApp(item.getHref());
assertNotNull(app);
for (Vm vm : app.getChildren()) {
assertEquals(connection.getVm(vm.getHref()), vm);
}
} catch (RuntimeException e) {
}

View File

@ -70,7 +70,7 @@ public class VAppHandlerTest {
.create("https://vcenterprise.bluelock.com/api/v1.0/vApp/vapp-607806320")));
assertEquals(vm.getDescription(), null);
assertEquals(vm.getTasks(), ImmutableList.of());
assertEquals(vm.getVAppScopedLocalId(), null);
assertEquals(vm.getVAppScopedLocalId(), "10_rhel_template");
}
}

View File

@ -72,7 +72,7 @@ public class VAppTemplateHandlerTest {
.create("https://vcenterprise.bluelock.com/api/v1.0/vAppTemplate/vappTemplate-1201908921")));
assertEquals(vm.getDescription(), null);
assertEquals(vm.getTasks(), ImmutableList.of());
assertEquals(vm.getVAppScopedLocalId(), null);
assertEquals(vm.getVAppScopedLocalId(), "02_ubuntu_template");
}
}

View File

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

View File

@ -1,5 +1,10 @@
<Vm deployed="false" status="8" name="RHEL5"
type="application/vnd.vmware.vcloud.vm+xml" href="https://vcenterprise.bluelock.com/api/v1.0/vApp/vm-2087535248">
<Vm xmlns="http://www.vmware.com/vcloud/v1" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"
xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData"
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"
deployed="false" status="8" name="RHEL5"
type="application/vnd.vmware.vcloud.vm+xml" href="https://vcenterprise.bluelock.com/api/v1.0/vApp/vm-2087535248"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_VirtualSystemSettingData.xsd http://schemas.dmtf.org/ovf/envelope/1 http://schemas.dmtf.org/ovf/envelope/1/dsp8023_1.1.0.xsd http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_ResourceAllocationSettingData.xsd http://www.vmware.com/vcloud/v1 http://vcenterprise.bluelock.com/api/v1.0/schema/master.xsd">
<Link rel="power:powerOn"
href="https://vcenterprise.bluelock.com/api/v1.0/vApp/vm-2087535248/power/action/powerOn" />
<Link rel="deploy" type="application/vnd.vmware.vcloud.deployVAppParams+xml"
@ -179,17 +184,7 @@
<AdminPasswordEnabled>true</AdminPasswordEnabled>
<AdminPasswordAuto>true</AdminPasswordAuto>
<ResetPasswordRequired>false</ResetPasswordRequired>
<CustomizationScript>#!/bin/bash if [[ $1 == "postcustomization"
]]; then echo "post customization" touch
/root/.postcustomization ping www.redhat.com -c 1 sleep 30 #
register with RHN /usr/sbin/rhnreg_ks --profilename
vic_`hostname`_`dmidecode -s system-uuid`
--activationkey=281c9a9c77b8c001fe8ac8dd3b3f76d6 --force
echo "rhn registered" # make hostname fully qualified to
speed up sendmail start perl -i -pe
"s/`hostname`/`hostname`.victory.blk/g"
/etc/sysconfig/network rm /etc/ssh/*_key* service sshd
restart echo "completed" fi</CustomizationScript>
<CustomizationScript>#!/bin/bash if [[ $1 == "postcustomization" ]]; then echo "post customization" touch /root/.postcustomization ping www.redhat.com -c 1 sleep 30 # register with RHN /usr/sbin/rhnreg_ks --profilename vic_`hostname`_`dmidecode -s system-uuid` --activationkey=XXXXXXXXXXXX --force echo "rhn registered" # make hostname fully qualified to speed up sendmail start perl -i -pe "s/`hostname`/`hostname`.victory.blk/g" /etc/sysconfig/network rm /etc/ssh/*_key* service sshd restart echo "completed" fi</CustomizationScript>
<ComputerName>RHEL5</ComputerName>
<Link rel="edit"
type="application/vnd.vmware.vcloud.guestCustomizationSection+xml"