added vm feature to savvis

This commit is contained in:
Adrian Cole 2011-03-23 17:50:57 -07:00
parent 26a3a2f9de
commit 208fb69af4
25 changed files with 1036 additions and 97 deletions

View File

@ -56,6 +56,8 @@
<test.savvis-symphonyvpdc.apiversion>0.8</test.savvis-symphonyvpdc.apiversion> <test.savvis-symphonyvpdc.apiversion>0.8</test.savvis-symphonyvpdc.apiversion>
<test.savvis-symphonyvpdc.identity>FIXME</test.savvis-symphonyvpdc.identity> <test.savvis-symphonyvpdc.identity>FIXME</test.savvis-symphonyvpdc.identity>
<test.savvis-symphonyvpdc.credential>FIXME</test.savvis-symphonyvpdc.credential> <test.savvis-symphonyvpdc.credential>FIXME</test.savvis-symphonyvpdc.credential>
<test.savvis-symphonyvpdc.loginUser>FIXME</test.savvis-symphonyvpdc.loginUser>
<test.savvis-symphonyvpdc.loginPassword>FIXME</test.savvis-symphonyvpdc.loginPassword>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
@ -100,6 +102,11 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.jamesmurty.utils</groupId>
<artifactId>java-xmlbuilder</artifactId>
<version>0.3</version>
</dependency>
</dependencies> </dependencies>
<profiles> <profiles>
<profile> <profile>
@ -134,6 +141,14 @@
<name>test.savvis-symphonyvpdc.credential</name> <name>test.savvis-symphonyvpdc.credential</name>
<value>${test.savvis-symphonyvpdc.credential}</value> <value>${test.savvis-symphonyvpdc.credential}</value>
</property> </property>
<property>
<name>test.savvis-symphonyvpdc.loginUser</name>
<value>${test.savvis-symphonyvpdc.loginUser}</value>
</property>
<property>
<name>test.savvis-symphonyvpdc.loginPassword</name>
<value>${test.savvis-symphonyvpdc.loginPassword}</value>
</property>
<property> <property>
<name>jclouds.compute.blacklist-nodes</name> <name>jclouds.compute.blacklist-nodes</name>
<value>${jclouds.compute.blacklist-nodes}</value> <value>${jclouds.compute.blacklist-nodes}</value>

View File

@ -25,6 +25,7 @@ import org.jclouds.compute.domain.CIMOperatingSystem;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.savvis.vpdc.domain.Resource; import org.jclouds.savvis.vpdc.domain.Resource;
import org.jclouds.savvis.vpdc.features.BrowsingAsyncClient; import org.jclouds.savvis.vpdc.features.BrowsingAsyncClient;
import org.jclouds.savvis.vpdc.features.VMAsyncClient;
import org.jclouds.savvis.vpdc.internal.Org; import org.jclouds.savvis.vpdc.internal.Org;
import com.google.inject.Provides; import com.google.inject.Provides;
@ -45,6 +46,12 @@ public interface VPDCAsyncClient {
@Delegate @Delegate
BrowsingAsyncClient getBrowsingClient(); BrowsingAsyncClient getBrowsingClient();
/**
* Provides asynchronous access to VM Operation features.
*/
@Delegate
VMAsyncClient getVMClient();
/** /**
* *
* @return a listing of all orgs that the current user has access to. * @return a listing of all orgs that the current user has access to.
@ -54,8 +61,8 @@ public interface VPDCAsyncClient {
Set<Resource> listOrgs(); Set<Resource> listOrgs();
/** /**
* predefined by default in the classpath resource {@code * predefined by default in the classpath resource
* /savvis-symphonyvpdc/predefined_operatingsystems.json} * {@code /savvis-symphonyvpdc/predefined_operatingsystems.json}
* *
* @return the operating systems that are predefined in the provider * @return the operating systems that are predefined in the provider
* @see <a href="https://api.sandbox.symphonyvpdc.savvis.net/doc/spec/api/addSingleVM.html" /> * @see <a href="https://api.sandbox.symphonyvpdc.savvis.net/doc/spec/api/addSingleVM.html" />

View File

@ -27,6 +27,7 @@ import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
import org.jclouds.savvis.vpdc.domain.Resource; import org.jclouds.savvis.vpdc.domain.Resource;
import org.jclouds.savvis.vpdc.features.BrowsingClient; import org.jclouds.savvis.vpdc.features.BrowsingClient;
import org.jclouds.savvis.vpdc.features.VMClient;
/** /**
* Provides synchronous access to VPDC. * Provides synchronous access to VPDC.
@ -45,6 +46,12 @@ public interface VPDCClient {
@Delegate @Delegate
BrowsingClient getBrowsingClient(); BrowsingClient getBrowsingClient();
/**
* Provides synchronous access to VM Operation features.
*/
@Delegate
VMClient getVMClient();
/** /**
* *
* @return a listing of all orgs that the current user has access to. * @return a listing of all orgs that the current user has access to.
@ -52,8 +59,8 @@ public interface VPDCClient {
Set<Resource> listOrgs(); Set<Resource> listOrgs();
/** /**
* predefined by default in the classpath resource {@code * predefined by default in the classpath resource
* /savvis-symphonyvpdc/predefined_operatingsystems.json} * {@code /savvis-symphonyvpdc/predefined_operatingsystems.json}
* *
* @return the operating systems that are predefined in the provider * @return the operating systems that are predefined in the provider
* @see <a href="https://api.sandbox.symphonyvpdc.savvis.net/doc/spec/api/addSingleVM.html" /> * @see <a href="https://api.sandbox.symphonyvpdc.savvis.net/doc/spec/api/addSingleVM.html" />

View File

@ -0,0 +1,201 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.savvis.vpdc.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import javax.inject.Singleton;
import javax.ws.rs.core.MediaType;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import org.jclouds.cim.ResourceAllocationSettingData.ResourceType;
import org.jclouds.compute.domain.CIMOperatingSystem;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.savvis.vpdc.domain.VMSpec;
import com.jamesmurty.utils.XMLBuilder;
/**
*
* @author Adrian Cole
*
*/
@Singleton
public class BindVMSpecToXmlPayload extends BindToStringPayload implements MapBinder {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
throw new IllegalStateException("BindVMSpecToXmlPayload needs parameters");
}
protected VMSpec findSpecInArgsOrNull(GeneratedHttpRequest<?> gRequest) {
for (Object arg : gRequest.getArgs()) {
if (arg instanceof VMSpec) {
return (VMSpec) arg;
} else if (arg instanceof VMSpec[]) {
VMSpec[] configuration = (VMSpec[]) arg;
return (configuration.length > 0) ? configuration[0] : null;
}
}
return null;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest<?>,
"this binder is only valid for GeneratedHttpRequests!");
GeneratedHttpRequest<?> gRequest = (GeneratedHttpRequest<?>) request;
checkState(gRequest.getArgs() != null, "args should be initialized at this point");
request = super.bindToRequest(request,
generateXml(findSpecInArgsOrNull(gRequest), postParams.get("name"), postParams.get("networkName")));
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_XML);
return request;
}
public String generateXml(VMSpec spec, String name, String networkName) {
checkNotNull(spec, "VMSpec");
checkNotNull(name, "name");
checkNotNull(networkName, "networkName");
try {
XMLBuilder rootBuilder = buildRootForName(name);
addOperatingSystemSection(rootBuilder, spec.getOperatingSystem());
addVirtualHardwareSection(rootBuilder, name, networkName, spec);
Properties outputProperties = new Properties();
outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes");
return rootBuilder.asString(outputProperties);
} catch (Exception e) {
return null;
}
}
void addVirtualHardwareSection(XMLBuilder rootBuilder, String name, String networkName, VMSpec spec) {
XMLBuilder virtualHardwareSectionBuilder = rootBuilder.e("ovf:VirtualHardwareSection");
virtualHardwareSectionBuilder.e("ovf:Info").t("Virtual Hardware");
addSystem(virtualHardwareSectionBuilder, name);
addItems(virtualHardwareSectionBuilder, spec, networkName);
}
void addItems(XMLBuilder virtualHardwareSectionBuilder, VMSpec spec, String networkName) {
//todo make this work with fractional, which I think means setting speed to half
addCPU(virtualHardwareSectionBuilder, (int)spec.getProcessorCount());
addMemory(virtualHardwareSectionBuilder, spec.getMemoryInGig());
addNetwork(virtualHardwareSectionBuilder, networkName);
addDisks(virtualHardwareSectionBuilder, spec);
}
private void addSystem(XMLBuilder virtualHardwareSectionBuilder, String name) {
XMLBuilder systemBuilder = virtualHardwareSectionBuilder.e("ovf:System");
systemBuilder.e("vssd:Description").t("Virtual Hardware Family");
systemBuilder.e("vssd:ElementName").t(name);
systemBuilder.e("vssd:InstanceID").t("1");
systemBuilder.e("vssd:VirtualSystemIdentifier").t(name);
}
private void addOperatingSystemSection(XMLBuilder rootBuilder, CIMOperatingSystem operatingSystem) {
XMLBuilder sectionBuilder = rootBuilder.e("ovf:OperatingSystemSection").a("ovf:id",
operatingSystem.getOsType().getCode() + "");
sectionBuilder.e("ovf:Info").t("Specifies the operating system installed");
sectionBuilder.e("ovf:Description").t(operatingSystem.getDescription());
}
private void addCPU(XMLBuilder sectionBuilder, int processorCount) {
XMLBuilder cpuBuilder = sectionBuilder.e("ovf:Item");
cpuBuilder.e("rasd:AllocationUnits").t("3 GHz");
cpuBuilder.e("rasd:Description").t("Number of Virtual CPUs");
cpuBuilder.e("rasd:ElementName").t(processorCount + " CPU");
cpuBuilder.e("rasd:InstanceID").t("1");
cpuBuilder.e("rasd:ResourceType").t(ResourceType.PROCESSOR.value());
cpuBuilder.e("rasd:VirtualQuantity").t(processorCount + "");
}
private void addMemory(XMLBuilder sectionBuilder, int memoryInGig) {
XMLBuilder memoryBuilder = sectionBuilder.e("ovf:Item");
memoryBuilder.e("rasd:AllocationUnits").t("Gigabytes");
memoryBuilder.e("rasd:Description").t("Memory Size");
memoryBuilder.e("rasd:ElementName").t("Memory");
memoryBuilder.e("rasd:InstanceID").t("2");
memoryBuilder.e("rasd:ResourceType").t(ResourceType.MEMORY.value());
memoryBuilder.e("rasd:VirtualQuantity").t(memoryInGig + "");
}
private void addNetwork(XMLBuilder sectionBuilder, String networkName) {
XMLBuilder networkBuilder = sectionBuilder.e("ovf:Item");
networkBuilder.e("rasd:Caption").t("false");
networkBuilder.e("rasd:Connection").t(networkName);
networkBuilder.e("rasd:ElementName").t("Network");
networkBuilder.e("rasd:InstanceID").t("3");
networkBuilder.e("rasd:ResourceType").t(ResourceType.ETHERNET_ADAPTER.value());
networkBuilder.e("rasd:VirtualQuantity").t("1");
}
private void addDisks(XMLBuilder sectionBuilder, VMSpec spec) {
XMLBuilder bootDiskBuilder = sectionBuilder.e("ovf:Item");
bootDiskBuilder.e("rasd:AllocationUnits").t("Gigabytes");
bootDiskBuilder.e("rasd:Caption").t("");
bootDiskBuilder.e("rasd:Description").t("Hard Disk");
bootDiskBuilder.e("rasd:ElementName").t(spec.getBootDeviceName());
bootDiskBuilder.e("rasd:HostResource").t("boot");
bootDiskBuilder.e("rasd:InstanceID").t("4");
bootDiskBuilder.e("rasd:ResourceType").t(ResourceType.BASE_PARTITIONABLE_UNIT.value());
bootDiskBuilder.e("rasd:VirtualQuantity").t(spec.getBootDiskSize() + "");
int instanceId = 5;
for (Entry<String, Integer> dataDisk : spec.getDataDiskDeviceNameToSizeInGig().entrySet()) {
XMLBuilder dataDiskBuilder = sectionBuilder.e("ovf:Item");
dataDiskBuilder.e("rasd:AllocationUnits").t("Gigabytes");
dataDiskBuilder.e("rasd:Caption").t("");
dataDiskBuilder.e("rasd:Description").t("Hard Disk");
dataDiskBuilder.e("rasd:ElementName").t(dataDisk.getKey());
dataDiskBuilder.e("rasd:HostResource").t("data");
dataDiskBuilder.e("rasd:InstanceID").t("" + instanceId++);
dataDiskBuilder.e("rasd:ResourceType").t(ResourceType.PARTITIONABLE_UNIT.value());
dataDiskBuilder.e("rasd:VirtualQuantity").t(dataDisk.getValue() + "");
}
}
protected XMLBuilder buildRootForName(String name) throws ParserConfigurationException, FactoryConfigurationError {
XMLBuilder rootBuilder = XMLBuilder.create("vApp:VApp")
.a("xmlns:common", "http://schemas.dmtf.org/wbem/wscim/1/common")
.a("xmlns:vApp", "http://www.vmware.com/vcloud/v0.8")
.a("xmlns:rasd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData")
.a("xmlns:vssd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData")
.a("xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1").a("name", name)
.a("type", "application/vnd.vmware.vcloud.vApp+xml").a("href", "");
return rootBuilder;
}
protected String ifNullDefaultTo(String value, String defaultValue) {
return value != null ? value : checkNotNull(defaultValue, "defaultValue");
}
}

View File

@ -25,7 +25,7 @@ import javax.inject.Singleton;
import org.jclouds.compute.config.BaseComputeServiceContextModule; import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.savvis.vpdc.domain.VApp; import org.jclouds.savvis.vpdc.domain.VM;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@ -38,15 +38,15 @@ import com.google.inject.Provides;
public class VPDCComputeServiceContextModule extends BaseComputeServiceContextModule { public class VPDCComputeServiceContextModule extends BaseComputeServiceContextModule {
@VisibleForTesting @VisibleForTesting
public static final Map<VApp.Status, NodeState> VAPPSTATUS_TO_NODESTATE = ImmutableMap public static final Map<VM.Status, NodeState> VAPPSTATUS_TO_NODESTATE = ImmutableMap
.<VApp.Status, NodeState> builder().put(VApp.Status.OFF, NodeState.SUSPENDED) .<VM.Status, NodeState> builder().put(VM.Status.OFF, NodeState.SUSPENDED)
.put(VApp.Status.ON, NodeState.RUNNING).put(VApp.Status.RESOLVED, NodeState.PENDING) .put(VM.Status.ON, NodeState.RUNNING).put(VM.Status.RESOLVED, NodeState.PENDING)
.put(VApp.Status.UNRECOGNIZED, NodeState.UNRECOGNIZED).put(VApp.Status.UNKNOWN, NodeState.UNRECOGNIZED) .put(VM.Status.UNRECOGNIZED, NodeState.UNRECOGNIZED).put(VM.Status.UNKNOWN, NodeState.UNRECOGNIZED)
.put(VApp.Status.SUSPENDED, NodeState.SUSPENDED).put(VApp.Status.UNRESOLVED, NodeState.PENDING).build(); .put(VM.Status.SUSPENDED, NodeState.SUSPENDED).put(VM.Status.UNRESOLVED, NodeState.PENDING).build();
@Singleton @Singleton
@Provides @Provides
protected Map<VApp.Status, NodeState> provideVAppStatusToNodeState() { protected Map<VM.Status, NodeState> provideVAppStatusToNodeState() {
return VAPPSTATUS_TO_NODESTATE; return VAPPSTATUS_TO_NODESTATE;
} }

View File

@ -53,6 +53,8 @@ import org.jclouds.savvis.vpdc.domain.Resource;
import org.jclouds.savvis.vpdc.domain.internal.VCloudSession; import org.jclouds.savvis.vpdc.domain.internal.VCloudSession;
import org.jclouds.savvis.vpdc.features.BrowsingAsyncClient; import org.jclouds.savvis.vpdc.features.BrowsingAsyncClient;
import org.jclouds.savvis.vpdc.features.BrowsingClient; import org.jclouds.savvis.vpdc.features.BrowsingClient;
import org.jclouds.savvis.vpdc.features.VMAsyncClient;
import org.jclouds.savvis.vpdc.features.VMClient;
import org.jclouds.savvis.vpdc.handlers.VPDCErrorHandler; import org.jclouds.savvis.vpdc.handlers.VPDCErrorHandler;
import org.jclouds.savvis.vpdc.internal.LoginAsyncClient; import org.jclouds.savvis.vpdc.internal.LoginAsyncClient;
import org.jclouds.savvis.vpdc.internal.VCloudToken; import org.jclouds.savvis.vpdc.internal.VCloudToken;
@ -89,7 +91,7 @@ public class VPDCRestClientModule extends RestClientModule<VPDCClient, VPDCAsync
@org.jclouds.savvis.vpdc.internal.Org @org.jclouds.savvis.vpdc.internal.Org
@Singleton @Singleton
protected Set<org.jclouds.savvis.vpdc.domain.Resource> provideOrgs(Supplier<VCloudSession> cache, protected Set<org.jclouds.savvis.vpdc.domain.Resource> provideOrgs(Supplier<VCloudSession> cache,
@Named(PROPERTY_IDENTITY) String user) { @Named(PROPERTY_IDENTITY) String user) {
VCloudSession discovery = cache.get(); VCloudSession discovery = cache.get();
checkState(discovery.getOrgs().size() > 0, "No orgs present for user: " + user); checkState(discovery.getOrgs().size() > 0, "No orgs present for user: " + user);
return discovery.getOrgs(); return discovery.getOrgs();
@ -107,13 +109,14 @@ public class VPDCRestClientModule extends RestClientModule<VPDCClient, VPDCAsync
@Provides @Provides
@Singleton @Singleton
protected Predicate<String> successTester(Injector injector, protected Predicate<String> successTester(Injector injector,
@Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) { @Named(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED) long completed) {
return new RetryablePredicate<String>(injector.getInstance(TaskSuccess.class), completed); return new RetryablePredicate<String>(injector.getInstance(TaskSuccess.class), completed);
} }
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()// public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(BrowsingClient.class, BrowsingAsyncClient.class)// .put(BrowsingClient.class, BrowsingAsyncClient.class)//
.build(); .put(VMClient.class, VMAsyncClient.class)//
.build();
public VPDCRestClientModule() { public VPDCRestClientModule() {
super(VPDCClient.class, VPDCAsyncClient.class, DELEGATE_MAP); super(VPDCClient.class, VPDCAsyncClient.class, DELEGATE_MAP);
@ -122,31 +125,33 @@ public class VPDCRestClientModule extends RestClientModule<VPDCClient, VPDCAsync
@Singleton @Singleton
@Provides @Provides
protected Set<CIMOperatingSystem> provideOperatingSystems(Json json, @Provider String providerName) protected Set<CIMOperatingSystem> provideOperatingSystems(Json json, @Provider String providerName)
throws IOException { throws IOException {
return json.fromJson(Strings2.toStringAndClose(getClass().getResourceAsStream( return json.fromJson(
"/" + providerName + "/predefined_operatingsystems.json")), new TypeLiteral<Set<CIMOperatingSystem>>() { Strings2.toStringAndClose(getClass().getResourceAsStream(
}.getType()); "/" + providerName + "/predefined_operatingsystems.json")),
new TypeLiteral<Set<CIMOperatingSystem>>() {
}.getType());
} }
@Provides @Provides
@Singleton @Singleton
protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, protected Supplier<VCloudSession> provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
final LoginAsyncClient login) { final LoginAsyncClient login) {
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<VCloudSession>(authException, seconds, return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<VCloudSession>(authException, seconds,
new Supplier<VCloudSession>() { new Supplier<VCloudSession>() {
@Override @Override
public VCloudSession get() { public VCloudSession get() {
try { try {
return login.login().get(10, TimeUnit.SECONDS); return login.login().get(10, TimeUnit.SECONDS);
} catch (Exception e) { } catch (Exception e) {
propagate(e); propagate(e);
assert false : e; assert false : e;
return null; return null;
}
} }
}
}); });
} }
@Override @Override

View File

@ -18,7 +18,7 @@ import com.google.common.collect.Sets;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class VApp extends Resource { public class VM extends Resource {
/** /**
* Objects such as vAppTemplate, vApp, and Vm have a status attribute whose value indicates the * Objects such as vAppTemplate, vApp, and Vm have a status attribute whose value indicates the
* state of the object. Status for an object, such as a vAppTemplate or vApp, whose Children (Vm * state of the object. Status for an object, such as a vAppTemplate or vApp, whose Children (Vm
@ -161,12 +161,12 @@ public class VApp extends Resource {
} }
@Override @Override
public VApp build() { public VM build() {
return new VApp(id, name, type, href, status, ipAddress, osType, osDescripton, networkSection, return new VM(id, name, type, href, status, ipAddress, osType, osDescripton, networkSection,
resourceAllocations); resourceAllocations);
} }
public static Builder fromVApp(VApp in) { public static Builder fromVApp(VM in) {
return new Builder().id(in.getId()).name(in.getName()).type(in.getType()).href(in.getHref()) return new Builder().id(in.getId()).name(in.getName()).type(in.getType()).href(in.getHref())
.status(in.getStatus()).ipAddress(in.getIpAddress()).osType(in.getOsType()) .status(in.getStatus()).ipAddress(in.getIpAddress()).osType(in.getOsType())
.networkSection(in.getNetworkSection()).resourceAllocations(in.getResourceAllocations()) .networkSection(in.getNetworkSection()).resourceAllocations(in.getResourceAllocations())
@ -202,7 +202,7 @@ public class VApp extends Resource {
private final NetworkSection networkSection; private final NetworkSection networkSection;
private final Set<ResourceAllocationSettingData> resourceAllocations; private final Set<ResourceAllocationSettingData> resourceAllocations;
public VApp(String id, String name, String type, URI href, Status status, String ipAddress, Integer osType, public VM(String id, String name, String type, URI href, Status status, String ipAddress, Integer osType,
String osDescripton, NetworkSection networkSection, Set<ResourceAllocationSettingData> resourceAllocations) { String osDescripton, NetworkSection networkSection, Set<ResourceAllocationSettingData> resourceAllocations) {
super(id, name, type, href); super(id, name, type, href);
this.status = status; this.status = status;

View File

@ -0,0 +1,214 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.savvis.vpdc.domain;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import org.jclouds.compute.domain.CIMOperatingSystem;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
/**
* A specification to launch a virtual machine
*
* @author Adrian Cole
*/
public class VMSpec {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private CIMOperatingSystem operatingSystem;
// TODO docs suggest fractions are possible, but xml isn't accepted on add
private float processorCount = 1f;
private int memoryInGig = 1;
private String bootDeviceName = "/";
// TODO doesn't seem to be changeable
private int bootDriveSize = 25;
private Map<String, Integer> dataDriveDeviceNameToSizeInGig = Maps.newLinkedHashMap();
public Builder operatingSystem(CIMOperatingSystem operatingSystem) {
this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem");
return this;
}
public Builder memoryInGig(int memoryInGig) {
checkArgument(memoryInGig > 0, "memoryInGig must be positive");
this.memoryInGig = memoryInGig;
return this;
}
public Builder processorCount(float processorCount) {
checkProcessorCount(processorCount);
this.processorCount = processorCount;
return this;
}
public Builder bootDeviceName(String bootDeviceName) {
this.bootDeviceName = checkNotNull(bootDeviceName, "bootDeviceName");
return this;
}
public Builder bootDiskSize(int bootDriveSize) {
checkArgument(bootDriveSize > 0, "bootDriveSize must be positive");
this.bootDriveSize = bootDriveSize;
return this;
}
public Builder addDataDrive(String dataDriveDeviceName, int sizeInGig) {
checkArgument(sizeInGig > 0, "sizeInGig must be positive");
this.dataDriveDeviceNameToSizeInGig.put(checkNotNull(dataDriveDeviceName, "dataDriveDeviceName"), sizeInGig);
return this;
}
public Builder addDataDrives(Map<String, Integer> dataDriveDeviceNameToSizeInGig) {
this.dataDriveDeviceNameToSizeInGig = ImmutableMap.copyOf(checkNotNull(dataDriveDeviceNameToSizeInGig,
"dataDriveDeviceNameToSizeInGig"));
return this;
}
public VMSpec build() {
return new VMSpec(operatingSystem, processorCount, memoryInGig, bootDeviceName, bootDriveSize,
dataDriveDeviceNameToSizeInGig);
}
public static Builder fromVMSpec(VMSpec in) {
return new Builder().operatingSystem(in.getOperatingSystem()).memoryInGig(in.getMemoryInGig())
.bootDeviceName(in.getBootDeviceName()).bootDiskSize(in.getBootDiskSize())
.addDataDrives(in.getDataDiskDeviceNameToSizeInGig()).processorCount(in.getProcessorCount());
}
}
static void checkProcessorCount(float processorCount) {
checkArgument(processorCount > 0, "processorCount must be positive and an increment of 0.5");
checkArgument(processorCount % .5 == 0, "processorCount must be an increment of 0.5");
}
private final CIMOperatingSystem operatingSystem;
private final float processorCount;
private final int memoryInGig;
private final String bootDeviceName;
private final int bootDriveSize;
private final Map<String, Integer> dataDriveDeviceNameToSizeInGig;
protected VMSpec(CIMOperatingSystem operatingSystem, float processorCount, int memoryInGig, String bootDeviceName,
int bootDriveSize, Map<String, Integer> dataDriveDeviceNameToSizeInGig) {
this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem not specified");
checkProcessorCount(processorCount);
this.processorCount = processorCount;
checkArgument(memoryInGig > 0, "memoryInGig must be positive");
this.memoryInGig = memoryInGig;
this.bootDeviceName = checkNotNull(bootDeviceName, "bootDeviceName name not specified");
checkArgument(bootDriveSize > 0, "bootDriveSize must be positive");
this.bootDriveSize = bootDriveSize;
this.dataDriveDeviceNameToSizeInGig = ImmutableMap.copyOf(checkNotNull(dataDriveDeviceNameToSizeInGig,
"dataDriveDeviceNameToSizeInGig"));
}
public CIMOperatingSystem getOperatingSystem() {
return operatingSystem;
}
public float getProcessorCount() {
return processorCount;
}
public int getMemoryInGig() {
return memoryInGig;
}
public Builder toBuilder() {
return Builder.fromVMSpec(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((bootDeviceName == null) ? 0 : bootDeviceName.hashCode());
result = prime * result + bootDriveSize;
result = prime * result
+ ((dataDriveDeviceNameToSizeInGig == null) ? 0 : dataDriveDeviceNameToSizeInGig.hashCode());
result = prime * result + memoryInGig;
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + Float.floatToIntBits(processorCount);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
VMSpec other = (VMSpec) obj;
if (bootDeviceName == null) {
if (other.bootDeviceName != null)
return false;
} else if (!bootDeviceName.equals(other.bootDeviceName))
return false;
if (bootDriveSize != other.bootDriveSize)
return false;
if (dataDriveDeviceNameToSizeInGig == null) {
if (other.dataDriveDeviceNameToSizeInGig != null)
return false;
} else if (!dataDriveDeviceNameToSizeInGig.equals(other.dataDriveDeviceNameToSizeInGig))
return false;
if (memoryInGig != other.memoryInGig)
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (Float.floatToIntBits(processorCount) != Float.floatToIntBits(other.processorCount))
return false;
return true;
}
public String getBootDeviceName() {
return bootDeviceName;
}
public int getBootDiskSize() {
return bootDriveSize;
}
public Map<String, Integer> getDataDiskDeviceNameToSizeInGig() {
return dataDriveDeviceNameToSizeInGig;
}
@Override
public String toString() {
return "[operatingSystem=" + operatingSystem + ", processorCount=" + processorCount + ", memoryInGig="
+ memoryInGig + ", bootDeviceName=" + bootDeviceName + ", bootDriveSize=" + bootDriveSize
+ ", dataDriveDeviceNameToSizeInGig=" + dataDriveDeviceNameToSizeInGig + "]";
}
}

View File

@ -33,16 +33,16 @@ import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.savvis.vpdc.domain.Network; import org.jclouds.savvis.vpdc.domain.Network;
import org.jclouds.savvis.vpdc.domain.Org; import org.jclouds.savvis.vpdc.domain.Org;
import org.jclouds.savvis.vpdc.domain.Task; import org.jclouds.savvis.vpdc.domain.Task;
import org.jclouds.savvis.vpdc.domain.VApp; import org.jclouds.savvis.vpdc.domain.VM;
import org.jclouds.savvis.vpdc.domain.VDC; import org.jclouds.savvis.vpdc.domain.VDC;
import org.jclouds.savvis.vpdc.filters.SetVCloudTokenCookie; import org.jclouds.savvis.vpdc.filters.SetVCloudTokenCookie;
import org.jclouds.savvis.vpdc.functions.DefaultOrgIfNull; import org.jclouds.savvis.vpdc.functions.DefaultOrgIfNull;
import org.jclouds.savvis.vpdc.options.BindGetVAppOptions; import org.jclouds.savvis.vpdc.options.BindGetVMOptions;
import org.jclouds.savvis.vpdc.options.GetVAppOptions; import org.jclouds.savvis.vpdc.options.GetVMOptions;
import org.jclouds.savvis.vpdc.xml.NetworkHandler; import org.jclouds.savvis.vpdc.xml.NetworkHandler;
import org.jclouds.savvis.vpdc.xml.OrgHandler; import org.jclouds.savvis.vpdc.xml.OrgHandler;
import org.jclouds.savvis.vpdc.xml.TaskHandler; import org.jclouds.savvis.vpdc.xml.TaskHandler;
import org.jclouds.savvis.vpdc.xml.VAppHandler; import org.jclouds.savvis.vpdc.xml.VMHandler;
import org.jclouds.savvis.vpdc.xml.VDCHandler; import org.jclouds.savvis.vpdc.xml.VDCHandler;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
@ -80,27 +80,27 @@ public interface BrowsingAsyncClient {
@PathParam("vpdcId") String vpdcId); @PathParam("vpdcId") String vpdcId);
/** /**
* @see BrowsingClient#getNetworkInOrgAndVDC * @see BrowsingClient#getNetworkInVDC
*/ */
@GET @GET
@XMLResponseParser(NetworkHandler.class) @XMLResponseParser(NetworkHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("org/{billingSiteId}/vdc/{vpdcId}/network/{network-tier-name}") @Path("org/{billingSiteId}/vdc/{vpdcId}/network/{network-tier-name}")
ListenableFuture<Network> getNetworkInOrgAndVDC( ListenableFuture<Network> getNetworkInVDC(
@PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId, @PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId,
@PathParam("vpdcId") String vpdcId, @PathParam("network-tier-name") String networkTierName); @PathParam("vpdcId") String vpdcId, @PathParam("network-tier-name") String networkTierName);
/** /**
* @see BrowsingClient#getVAppInOrgAndVDC * @see BrowsingClient#getVMInVDC
*/ */
@GET @GET
@XMLResponseParser(VAppHandler.class) @XMLResponseParser(VMHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
@Path("org/{billingSiteId}/vdc/{vpdcId}/vApp/{vAppId}") @Path("org/{billingSiteId}/vdc/{vpdcId}/vApp/{vAppId}")
ListenableFuture<VApp> getVAppInOrgAndVDC( ListenableFuture<VM> getVMInVDC(
@PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId, @PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId,
@PathParam("vpdcId") String vpdcId, @PathParam("vAppId") String vAppId, @PathParam("vpdcId") String vpdcId, @PathParam("vAppId") String vAppId,
@BinderParam(BindGetVAppOptions.class) GetVAppOptions... options); @BinderParam(BindGetVMOptions.class) GetVMOptions... options);
/** /**
* @see BrowsingClient#getTask * @see BrowsingClient#getTask

View File

@ -27,9 +27,9 @@ import org.jclouds.concurrent.Timeout;
import org.jclouds.savvis.vpdc.domain.Network; import org.jclouds.savvis.vpdc.domain.Network;
import org.jclouds.savvis.vpdc.domain.Org; import org.jclouds.savvis.vpdc.domain.Org;
import org.jclouds.savvis.vpdc.domain.Task; import org.jclouds.savvis.vpdc.domain.Task;
import org.jclouds.savvis.vpdc.domain.VApp; import org.jclouds.savvis.vpdc.domain.VM;
import org.jclouds.savvis.vpdc.domain.VDC; import org.jclouds.savvis.vpdc.domain.VDC;
import org.jclouds.savvis.vpdc.options.GetVAppOptions; import org.jclouds.savvis.vpdc.options.GetVMOptions;
/** /**
* Provides access to Symphony VPDC resources via their REST API. * Provides access to Symphony VPDC resources via their REST API.
@ -73,7 +73,7 @@ public interface BrowsingClient {
* @return network detail if it used any one deployed VM and NetworkConfigSection defines various * @return network detail if it used any one deployed VM and NetworkConfigSection defines various
* network features such NAT Public IP, Gateway and Netmask, or null if not present * network features such NAT Public IP, Gateway and Netmask, or null if not present
*/ */
Network getNetworkInOrgAndVDC(String billingSiteId, String vpdcId, String networkTierName); Network getNetworkInVDC(String billingSiteId, String vpdcId, String networkTierName);
/** /**
* VAPP is a software solution, the API returns details of virtual machine configuration such as * VAPP is a software solution, the API returns details of virtual machine configuration such as
@ -92,14 +92,14 @@ public interface BrowsingClient {
* machines, all of which are deployed, managed, and maintained as a unit, or null if not * machines, all of which are deployed, managed, and maintained as a unit, or null if not
* present * present
*/ */
VApp getVAppInOrgAndVDC(String billingSiteId, String vpdcId, String vAppId, GetVAppOptions... options); VM getVMInVDC(String billingSiteId, String vpdcId, String vAppId, GetVMOptions... options);
/** /**
* Gets an existing task. * Gets an existing task.
* *
* @param taskId * @param taskId
* task id * task id
* @return If the request is successful, caller could get the VApp/VMDK details as specified in * @return If the request is successful, caller could get the VM/VMDK details as specified in
* the result element and if the request is not successful, caller would get empty * the result element and if the request is not successful, caller would get empty
* VAPP/VMDK URL and respective validation (error) message. * VAPP/VMDK URL and respective validation (error) message.
*/ */

View File

@ -0,0 +1,78 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.savvis.vpdc.features;
import javax.annotation.Nullable;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.ParamParser;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.savvis.vpdc.binders.BindVMSpecToXmlPayload;
import org.jclouds.savvis.vpdc.domain.Task;
import org.jclouds.savvis.vpdc.domain.VMSpec;
import org.jclouds.savvis.vpdc.filters.SetVCloudTokenCookie;
import org.jclouds.savvis.vpdc.functions.DefaultOrgIfNull;
import org.jclouds.savvis.vpdc.xml.TaskHandler;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to Symphony VPDC resources via their REST API.
* <p/>
*
* @see <a href="https://api.sandbox.symphonyvpdc.savvis.net/doc/spec/api/index.html" />
* @author Adrian Cole
*/
@RequestFilters(SetVCloudTokenCookie.class)
@Path("v{jclouds.api-version}")
public interface VMAsyncClient {
/**
* @see VMClient#addVMIntoVDC
*/
@GET
@XMLResponseParser(TaskHandler.class)
@Path("org/{billingSiteId}/vdc/{vpdcId}/vApp/")
@MapBinder(BindVMSpecToXmlPayload.class)
ListenableFuture<Task> addVMIntoVDC(
@PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId,
@PathParam("vpdcId") String vpdcId, @PayloadParam("networkName") String networkTierName,
@PayloadParam("name") String vAppName, VMSpec spec);
/**
* @see VMClient#removeVMFromVDC
*/
@DELETE
@XMLResponseParser(TaskHandler.class)
@Path("org/{billingSiteId}/vdc/{vpdcId}/vApp/{vAppId}")
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Task> removeVMFromVDC(
@PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId,
@PathParam("vpdcId") String vpdcId, @PathParam("vAppId") String vAppId);
}

View File

@ -0,0 +1,72 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.savvis.vpdc.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.savvis.vpdc.domain.Task;
import org.jclouds.savvis.vpdc.domain.VMSpec;
/**
* Provides access to Symphony VPDC resources via their REST API.
* <p/>
*
* @see <a href="https://api.sandbox.symphonyvpdc.savvis.net/doc/spec/api/" />
* @author Adrian Cole
*/
@Timeout(duration = 300, timeUnit = TimeUnit.SECONDS)
public interface VMClient {
/**
* Add/Deploy new VM into VDC
*
* @param billingSiteId
* billing site Id, or null for default
* @param vpdcId
* vpdc Id
* @param networkTierName
* network tier name
* @param spec
* how to
*
* @return VM in progress
*/
Task addVMIntoVDC(String billingSiteId, String vpdcId, String networkTierName, String name, VMSpec spec);
/**
* Remove a VM
* <p/>
* <h4>Pre-conditions:</h4>
*
* <ul>
* <li>No snapshot has been created for the VM.</li>
* <li>For Balanced profile, the VM must not be associated with any firewall rule and/or included
* in a load balancing pool.</li>
* </ul>
*
* @param billingSiteId
* @param vpdcId
* @param vAppId
* @return
*/
Task removeVMFromVDC(String billingSiteId, String vpdcId, String vAppId);
}

View File

@ -15,19 +15,19 @@ import org.jclouds.rest.Binder;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class BindGetVAppOptions implements Binder { public class BindGetVMOptions implements Binder {
private final Provider<UriBuilder> uriBuilder; private final Provider<UriBuilder> uriBuilder;
@Inject @Inject
public BindGetVAppOptions(Provider<UriBuilder> uriBuilder) { public BindGetVMOptions(Provider<UriBuilder> uriBuilder) {
this.uriBuilder = uriBuilder; this.uriBuilder = uriBuilder;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) { public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(input instanceof GetVAppOptions[], "this binder is only valid for GetVAppOptions!"); checkArgument(input instanceof GetVMOptions[], "this binder is only valid for GetVAppOptions!");
GetVAppOptions[] options = GetVAppOptions[].class.cast(input); GetVMOptions[] options = GetVMOptions[].class.cast(input);
if (options.length > 0 && options[0].isWithPowerState()) if (options.length > 0 && options[0].isWithPowerState())
return (R) request.toBuilder().endpoint( return (R) request.toBuilder().endpoint(
uriBuilder.get().uri(request.getEndpoint()).path("withpowerstate").build()).build(); uriBuilder.get().uri(request.getEndpoint()).path("withpowerstate").build()).build();

View File

@ -30,21 +30,21 @@ package org.jclouds.savvis.vpdc.options;
* import static org.jclouds.savvis.vpdc.options.GetVAppOptions.Builder.* * import static org.jclouds.savvis.vpdc.options.GetVAppOptions.Builder.*
* <p/> * <p/>
* *
* vApp = context.getApi().getBrowsingClient().getVAppInOrgAndVDC(orgId, vdcId, vAppId, withPowerState()); * vApp = context.getApi().getBrowsingClient().getVAppInVDC(orgId, vdcId, vAppId, withPowerState());
* <code> * <code>
* *
* @author Adrian Cole * @author Adrian Cole
* @see <a href= "https://api.sandbox.symphonyvpdc.savvis.net/doc/spec/api/getVAppPowerState.html" * @see <a href= "https://api.sandbox.symphonyvpdc.savvis.net/doc/spec/api/getVAppPowerState.html"
* /> * />
*/ */
public class GetVAppOptions { public class GetVMOptions {
public static final GetVAppOptions NONE = new GetVAppOptions(); public static final GetVMOptions NONE = new GetVMOptions();
private boolean withPowerState; private boolean withPowerState;
/** /**
* The VM State is the real time state. * The VM State is the real time state.
*/ */
public GetVAppOptions withPowerState() { public GetVMOptions withPowerState() {
this.withPowerState = true; this.withPowerState = true;
return this; return this;
} }
@ -56,10 +56,10 @@ public class GetVAppOptions {
public static class Builder { public static class Builder {
/** /**
* @see GetVAppOptions#withPowerState() * @see GetVMOptions#withPowerState()
*/ */
public static GetVAppOptions withPowerState() { public static GetVMOptions withPowerState() {
GetVAppOptions options = new GetVAppOptions(); GetVMOptions options = new GetVMOptions();
return options.withPowerState(); return options.withPowerState();
} }

View File

@ -29,7 +29,7 @@ import org.jclouds.cim.xml.ResourceAllocationSettingDataHandler;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.ovf.xml.NetworkSectionHandler; import org.jclouds.ovf.xml.NetworkSectionHandler;
import org.jclouds.savvis.vpdc.domain.Resource; import org.jclouds.savvis.vpdc.domain.Resource;
import org.jclouds.savvis.vpdc.domain.VApp; import org.jclouds.savvis.vpdc.domain.VM;
import org.jclouds.savvis.vpdc.util.Utils; import org.jclouds.savvis.vpdc.util.Utils;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@ -39,25 +39,25 @@ import com.google.common.collect.ImmutableMap;
/** /**
* @author Kedar Dave * @author Kedar Dave
*/ */
public class VAppHandler extends ParseSax.HandlerWithResult<VApp> { public class VMHandler extends ParseSax.HandlerWithResult<VM> {
protected StringBuilder currentText = new StringBuilder(); protected StringBuilder currentText = new StringBuilder();
private final NetworkSectionHandler networkSectionHandler; private final NetworkSectionHandler networkSectionHandler;
private final ResourceAllocationSettingDataHandler allocationHandler; private final ResourceAllocationSettingDataHandler allocationHandler;
@Inject @Inject
public VAppHandler(NetworkSectionHandler networkSectionHandler, ResourceAllocationSettingDataHandler allocationHandler) { public VMHandler(NetworkSectionHandler networkSectionHandler, ResourceAllocationSettingDataHandler allocationHandler) {
this.networkSectionHandler = networkSectionHandler; this.networkSectionHandler = networkSectionHandler;
this.allocationHandler = allocationHandler; this.allocationHandler = allocationHandler;
} }
private VApp.Builder builder = VApp.builder(); private VM.Builder builder = VM.builder();
protected boolean inOs; protected boolean inOs;
public VApp getResult() { public VM getResult() {
try { try {
return builder.build(); return builder.build();
} finally { } finally {
builder = VApp.builder(); builder = VM.builder();
} }
} }
@ -70,7 +70,7 @@ public class VAppHandler extends ParseSax.HandlerWithResult<VApp> {
.put("href", getRequest().getEndpoint().toASCIIString()).build(); .put("href", getRequest().getEndpoint().toASCIIString()).build();
Resource vApp = newResource(attributes); Resource vApp = newResource(attributes);
builder.name(vApp.getName()).type(vApp.getType()).id(vApp.getId()).href(vApp.getHref()); builder.name(vApp.getName()).type(vApp.getType()).id(vApp.getId()).href(vApp.getHref());
builder.status(VApp.Status.fromValue(attributes.get("status"))); builder.status(VM.Status.fromValue(attributes.get("status")));
} else if (qName.endsWith("OperatingSystemSection")) { } else if (qName.endsWith("OperatingSystemSection")) {
inOs = true; inOs = true;
if (attributes.containsKey("id")) if (attributes.containsKey("id"))

View File

@ -16,7 +16,7 @@
"osType": "RHEL" "osType": "RHEL"
}, },
{ {
"family": "RHEL_64", "family": "RHEL",
"name": "rhel5_64Guest", "name": "rhel5_64Guest",
"version": "5", "version": "5",
"description": "Red Hat Enterprise Linux 5.x 64bit", "description": "Red Hat Enterprise Linux 5.x 64bit",

View File

@ -45,6 +45,7 @@ public class VPDCAsyncClientTest extends BaseVPDCAsyncClientTest<VPDCAsyncClient
public void testSync() { public void testSync() {
assert syncClient.getBrowsingClient() != null; assert syncClient.getBrowsingClient() != null;
assert syncClient.getVMClient() != null;
assertEquals(syncClient.listOrgs().size(), 1); assertEquals(syncClient.listOrgs().size(), 1);
assertEquals(syncClient.listPredefinedOperatingSystems().size(), 3); assertEquals(syncClient.listPredefinedOperatingSystems().size(), 3);
@ -52,6 +53,7 @@ public class VPDCAsyncClientTest extends BaseVPDCAsyncClientTest<VPDCAsyncClient
public void testAsync() { public void testAsync() {
assert asyncClient.getBrowsingClient() != null; assert asyncClient.getBrowsingClient() != null;
assert asyncClient.getVMClient() != null;
assertEquals(asyncClient.listOrgs().size(), 1); assertEquals(asyncClient.listOrgs().size(), 1);
assertEquals(asyncClient.listPredefinedOperatingSystems().size(), 3); assertEquals(asyncClient.listPredefinedOperatingSystems().size(), 3);

View File

@ -0,0 +1,66 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.savvis.vpdc.binders;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Set;
import org.jclouds.cim.OSType;
import org.jclouds.compute.domain.CIMOperatingSystem;
import org.jclouds.savvis.vpdc.domain.VMSpec;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.gson.Gson;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code BindVMSpecToXmlPayload}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class BindVMSpecToXmlPayloadTest {
public void test() throws IOException {
CIMOperatingSystem os = Iterables.find(new Gson().<Set<CIMOperatingSystem>> fromJson(
Strings2.toStringAndClose(getClass().getResourceAsStream(
"/savvis-symphonyvpdc/predefined_operatingsystems.json")),
new TypeLiteral<Set<CIMOperatingSystem>>() {
}.getType()), new Predicate<CIMOperatingSystem>() {
@Override
public boolean apply(CIMOperatingSystem arg0) {
return arg0.getOsType() == OSType.RHEL_64;
}
});
String expected = Strings2.toStringAndClose(getClass().getResourceAsStream("/vm-default.xml"));
VMSpec spec = VMSpec.builder().operatingSystem(os).build();
assertEquals(new BindVMSpecToXmlPayload().generateXml(spec, "DemoHost-1", "VM Tier01"), expected);
}
}

View File

@ -28,12 +28,16 @@ import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
import org.jclouds.savvis.vpdc.VPDCAsyncClient; import org.jclouds.savvis.vpdc.VPDCAsyncClient;
import org.jclouds.savvis.vpdc.VPDCClient; import org.jclouds.savvis.vpdc.VPDCClient;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module; import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/** /**
* Tests behavior of {@code VPDCClient} * Tests behavior of {@code VPDCClient}
@ -49,11 +53,12 @@ public class BaseVPDCClientLiveTest {
protected String credential; protected String credential;
protected String endpoint; protected String endpoint;
protected String apiversion; protected String apiversion;
protected Injector injector;
protected void setupCredentials() { protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"); identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential"); + ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint"); endpoint = System.getProperty("test." + provider + ".endpoint");
apiversion = System.getProperty("test." + provider + ".apiversion"); apiversion = System.getProperty("test." + provider + ".apiversion");
} }
@ -73,8 +78,13 @@ public class BaseVPDCClientLiveTest {
public void setupClient() { public void setupClient() {
setupCredentials(); setupCredentials();
Properties overrides = setupProperties(); Properties overrides = setupProperties();
context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()), // context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new
overrides); // Log4JLoggingModule()),
// overrides);
injector = new RestContextFactory().createContextBuilder(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides).buildInjector();
context = injector.getInstance(Key.get(new TypeLiteral<RestContext<VPDCClient, VPDCAsyncClient>>() {
}));
} }
@AfterGroups(groups = "live") @AfterGroups(groups = "live")

View File

@ -26,11 +26,11 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.savvis.vpdc.options.GetVAppOptions; import org.jclouds.savvis.vpdc.options.GetVMOptions;
import org.jclouds.savvis.vpdc.xml.NetworkHandler; import org.jclouds.savvis.vpdc.xml.NetworkHandler;
import org.jclouds.savvis.vpdc.xml.OrgHandler; import org.jclouds.savvis.vpdc.xml.OrgHandler;
import org.jclouds.savvis.vpdc.xml.TaskHandler; import org.jclouds.savvis.vpdc.xml.TaskHandler;
import org.jclouds.savvis.vpdc.xml.VAppHandler; import org.jclouds.savvis.vpdc.xml.VMHandler;
import org.jclouds.savvis.vpdc.xml.VDCHandler; import org.jclouds.savvis.vpdc.xml.VDCHandler;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -105,7 +105,7 @@ public class BrowsingAsyncClientTest extends BaseVPDCAsyncClientTest<BrowsingAsy
} }
public void testNetwork() throws SecurityException, NoSuchMethodException, IOException { public void testNetwork() throws SecurityException, NoSuchMethodException, IOException {
Method method = BrowsingAsyncClient.class.getMethod("getNetworkInOrgAndVDC", String.class, String.class, Method method = BrowsingAsyncClient.class.getMethod("getNetworkInVDC", String.class, String.class,
String.class); String.class);
HttpRequest request = processor.createRequest(method, "11", "22", "VM-Tier01"); HttpRequest request = processor.createRequest(method, "11", "22", "VM-Tier01");
@ -122,7 +122,7 @@ public class BrowsingAsyncClientTest extends BaseVPDCAsyncClientTest<BrowsingAsy
} }
public void testNetworkWhenOrgNull() throws SecurityException, NoSuchMethodException, IOException { public void testNetworkWhenOrgNull() throws SecurityException, NoSuchMethodException, IOException {
Method method = BrowsingAsyncClient.class.getMethod("getNetworkInOrgAndVDC", String.class, String.class, Method method = BrowsingAsyncClient.class.getMethod("getNetworkInVDC", String.class, String.class,
String.class); String.class);
HttpRequest request = processor.createRequest(method, (String) null, "22", "VM-Tier01"); HttpRequest request = processor.createRequest(method, (String) null, "22", "VM-Tier01");
@ -138,9 +138,9 @@ public class BrowsingAsyncClientTest extends BaseVPDCAsyncClientTest<BrowsingAsy
checkFilters(request); checkFilters(request);
} }
public void testVApp() throws SecurityException, NoSuchMethodException, IOException { public void testVM() throws SecurityException, NoSuchMethodException, IOException {
Method method = BrowsingAsyncClient.class.getMethod("getVAppInOrgAndVDC", String.class, String.class, Method method = BrowsingAsyncClient.class.getMethod("getVMInVDC", String.class, String.class,
String.class, GetVAppOptions[].class); String.class, GetVMOptions[].class);
HttpRequest request = processor.createRequest(method, "11", "22", "VM-Tier01"); HttpRequest request = processor.createRequest(method, "11", "22", "VM-Tier01");
assertRequestLineEquals(request, assertRequestLineEquals(request,
@ -149,16 +149,16 @@ public class BrowsingAsyncClientTest extends BaseVPDCAsyncClientTest<BrowsingAsy
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VAppHandler.class); assertSaxResponseParserClassEquals(method, VMHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request); checkFilters(request);
} }
public void testVAppWithPowerState() throws SecurityException, NoSuchMethodException, IOException { public void testVMWithPowerState() throws SecurityException, NoSuchMethodException, IOException {
Method method = BrowsingAsyncClient.class.getMethod("getVAppInOrgAndVDC", String.class, String.class, Method method = BrowsingAsyncClient.class.getMethod("getVMInVDC", String.class, String.class,
String.class, GetVAppOptions[].class); String.class, GetVMOptions[].class);
HttpRequest request = processor.createRequest(method, "11", "22", "VM-Tier01", GetVAppOptions.Builder HttpRequest request = processor.createRequest(method, "11", "22", "VM-Tier01", GetVMOptions.Builder
.withPowerState()); .withPowerState());
assertRequestLineEquals(request, assertRequestLineEquals(request,
@ -167,15 +167,15 @@ public class BrowsingAsyncClientTest extends BaseVPDCAsyncClientTest<BrowsingAsy
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VAppHandler.class); assertSaxResponseParserClassEquals(method, VMHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request); checkFilters(request);
} }
public void testVAppWhenOrgNull() throws SecurityException, NoSuchMethodException, IOException { public void testVMWhenOrgNull() throws SecurityException, NoSuchMethodException, IOException {
Method method = BrowsingAsyncClient.class.getMethod("getVAppInOrgAndVDC", String.class, String.class, Method method = BrowsingAsyncClient.class.getMethod("getVMInVDC", String.class, String.class,
String.class, GetVAppOptions[].class); String.class, GetVMOptions[].class);
HttpRequest request = processor.createRequest(method, (String) null, "22", "VM-Tier01"); HttpRequest request = processor.createRequest(method, (String) null, "22", "VM-Tier01");
assertRequestLineEquals(request, assertRequestLineEquals(request,
@ -184,7 +184,7 @@ public class BrowsingAsyncClientTest extends BaseVPDCAsyncClientTest<BrowsingAsy
assertPayloadEquals(request, null, null, false); assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class); assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, VAppHandler.class); assertSaxResponseParserClassEquals(method, VMHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request); checkFilters(request);

View File

@ -19,14 +19,14 @@
package org.jclouds.savvis.vpdc.features; package org.jclouds.savvis.vpdc.features;
import static org.jclouds.savvis.vpdc.options.GetVAppOptions.Builder.withPowerState; import static org.jclouds.savvis.vpdc.options.GetVMOptions.Builder.withPowerState;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import org.jclouds.savvis.vpdc.domain.Network; import org.jclouds.savvis.vpdc.domain.Network;
import org.jclouds.savvis.vpdc.domain.Org; import org.jclouds.savvis.vpdc.domain.Org;
import org.jclouds.savvis.vpdc.domain.Resource; import org.jclouds.savvis.vpdc.domain.Resource;
import org.jclouds.savvis.vpdc.domain.VApp; import org.jclouds.savvis.vpdc.domain.VM;
import org.jclouds.savvis.vpdc.domain.VDC; import org.jclouds.savvis.vpdc.domain.VDC;
import org.jclouds.savvis.vpdc.reference.VCloudMediaType; import org.jclouds.savvis.vpdc.reference.VCloudMediaType;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
@ -92,7 +92,7 @@ public class BrowsingClientLiveTest extends BaseVPDCClientLiveTest {
for (Resource vdc : org.getVDCs()) { for (Resource vdc : org.getVDCs()) {
VDC VDC = client.getVDCInOrg(org.getId(), vdc.getId()); VDC VDC = client.getVDCInOrg(org.getId(), vdc.getId());
for (Resource vApp : VDC.getAvailableNetworks()) { for (Resource vApp : VDC.getAvailableNetworks()) {
Network response = client.getNetworkInOrgAndVDC(org.getId(), vdc.getId(), vApp.getId()); Network response = client.getNetworkInVDC(org.getId(), vdc.getId(), vApp.getId());
assertNotNull(response); assertNotNull(response);
assertNotNull(response.getId()); assertNotNull(response.getId());
assertNotNull(response.getHref()); assertNotNull(response.getHref());
@ -101,7 +101,7 @@ public class BrowsingClientLiveTest extends BaseVPDCClientLiveTest {
assertNotNull(response.getNetmask()); assertNotNull(response.getNetmask());
assertNotNull(response.getGateway()); assertNotNull(response.getGateway());
assertNotNull(response.getInternalToExternalNATRules()); assertNotNull(response.getInternalToExternalNATRules());
assertEquals(client.getNetworkInOrgAndVDC(org.getId(), vdc.getId(), response.getId()).toString(), assertEquals(client.getNetworkInVDC(org.getId(), vdc.getId(), response.getId()).toString(),
response.toString()); response.toString());
} }
} }
@ -109,7 +109,7 @@ public class BrowsingClientLiveTest extends BaseVPDCClientLiveTest {
} }
@Test @Test
public void testVApp() throws Exception { public void testVM() throws Exception {
for (Resource org1 : context.getApi().listOrgs()) { for (Resource org1 : context.getApi().listOrgs()) {
Org org = client.getOrg(org1.getId()); Org org = client.getOrg(org1.getId());
for (Resource vdc : org.getVDCs()) { for (Resource vdc : org.getVDCs()) {
@ -122,7 +122,7 @@ public class BrowsingClientLiveTest extends BaseVPDCClientLiveTest {
} }
})) { })) {
VApp response = client.getVAppInOrgAndVDC(org.getId(), vdc.getId(), vApp.getId()); VM response = client.getVMInVDC(org.getId(), vdc.getId(), vApp.getId());
assertNotNull(response); assertNotNull(response);
assertNotNull(response.getId()); assertNotNull(response.getId());
assertNotNull(response.getHref()); assertNotNull(response.getHref());
@ -135,7 +135,7 @@ public class BrowsingClientLiveTest extends BaseVPDCClientLiveTest {
assertNotNull(response.getNetworkSection()); assertNotNull(response.getNetworkSection());
assertNotNull(response.getResourceAllocations()); assertNotNull(response.getResourceAllocations());
// power state is the only thing that should change // power state is the only thing that should change
assertEquals(client.getVAppInOrgAndVDC(org.getId(), vdc.getId(), response.getId(), withPowerState()) assertEquals(client.getVMInVDC(org.getId(), vdc.getId(), response.getId(), withPowerState())
.toString().replaceFirst("status=[A-Z]+", ""), response.toString().replaceFirst( .toString().replaceFirst("status=[A-Z]+", ""), response.toString().replaceFirst(
"status=[A-Z]+", "")); "status=[A-Z]+", ""));
} }

View File

@ -0,0 +1,103 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.savvis.vpdc.features;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Set;
import org.jclouds.cim.OSType;
import org.jclouds.compute.domain.CIMOperatingSystem;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.savvis.vpdc.domain.VMSpec;
import org.jclouds.savvis.vpdc.xml.TaskHandler;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
/**
* Tests annotation parsing of {@code VMAsyncClient}
*
* @author Adrian Cole
*/
@Test(groups = "unit")
public class VMAsyncClientTest extends BaseVPDCAsyncClientTest<VMAsyncClient> {
public void testAddVMIntoVDC() throws SecurityException, NoSuchMethodException, IOException {
Method method = VMAsyncClient.class.getMethod("addVMIntoVDC", String.class, String.class, String.class,
String.class, VMSpec.class);
CIMOperatingSystem os = Iterables.find(injector.getInstance(Key.get(new TypeLiteral<Set<CIMOperatingSystem>>() {
})), new Predicate<CIMOperatingSystem>() {
@Override
public boolean apply(CIMOperatingSystem arg0) {
return arg0.getOsType() == OSType.RHEL_64;
}
});
HttpRequest request = processor.createRequest(method, "11", "22", "VM Tier01", "DemoHost-1", VMSpec.builder()
.operatingSystem(os).build());
assertRequestLineEquals(request,
"GET https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/vm-default.xml")),
"application/xml", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, TaskHandler.class);
assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class);
checkFilters(request);
}
public void testRemoveVM() throws SecurityException, NoSuchMethodException, IOException {
Method method = VMAsyncClient.class.getMethod("removeVMFromVDC", String.class, String.class, String.class);
HttpRequest request = processor.createRequest(method, "11", "22", "VM-Tier01");
assertRequestLineEquals(request,
"DELETE https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/VM-Tier01 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, TaskHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(request);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<VMAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<VMAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,140 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.savvis.vpdc.features;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.cim.OSType;
import org.jclouds.compute.domain.CIMOperatingSystem;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.domain.Credentials;
import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.savvis.vpdc.domain.Task;
import org.jclouds.savvis.vpdc.domain.VM;
import org.jclouds.savvis.vpdc.domain.VMSpec;
import org.jclouds.savvis.vpdc.predicates.TaskSuccess;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshClient.Factory;
import org.jclouds.util.InetAddresses2;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.net.HostSpecifier;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
@Test(groups = "live")
public class VMClientLiveTest extends BaseVPDCClientLiveTest {
private VMClient client;
private Factory sshFactory;
private VM vm;
private RetryablePredicate<IPSocket> socketTester;
private RetryablePredicate<String> taskTester;
private String username = checkNotNull(System.getProperty("test." + provider + ".loginUser"), "test." + provider
+ ".loginUser");
private String password = checkNotNull(System.getProperty("test." + provider + ".loginPassword"), "test." + provider
+ ".loginPassword");
@Override
@BeforeGroups(groups = { "live" })
public void setupClient() {
super.setupClient();
client = context.getApi().getVMClient();
sshFactory = injector.getInstance(SshClient.Factory.class);
socketTester = new RetryablePredicate<IPSocket>(injector.getInstance(SocketOpen.class), 130, 10, TimeUnit.SECONDS);// make
taskTester = new RetryablePredicate<String>(injector.getInstance(TaskSuccess.class), 650, 10, TimeUnit.SECONDS);
}
protected String prefix = System.getProperty("user.name");
private String billingSiteId;
private String vpdcId;
public void testCreateVirtualMachine() throws Exception {
billingSiteId = context.getApi().getBrowsingClient().getOrg(null).getId();// default
vpdcId = Iterables.get(context.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), 0).getId();
String networkTierName = Iterables.get(
context.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId).getAvailableNetworks(), 0)
.getName();
String name = prefix;
CIMOperatingSystem os = Iterables.find(injector.getInstance(Key.get(new TypeLiteral<Set<CIMOperatingSystem>>() {
})), new Predicate<CIMOperatingSystem>() {
@Override
public boolean apply(CIMOperatingSystem arg0) {
return arg0.getOsType() == OSType.RHEL_64;
}
});
System.out.printf("vpdcId %s, networkName %s, name %s, os %s%n", vpdcId, networkTierName, name, os);
Task task = client.addVMIntoVDC(billingSiteId, vpdcId, networkTierName, name, VMSpec.builder()
.operatingSystem(os).build());
assert this.taskTester.apply(task.getId());
vm = context.getApi().getBrowsingClient().getVMInVDC(billingSiteId, vpdcId, task.getOwner().getId());
conditionallyCheckSSH();
}
private void conditionallyCheckSSH() {
assert HostSpecifier.isValid(vm.getIpAddress());
if (!InetAddresses2.isPrivateIPAddress(vm.getIpAddress())) {
// not sure if the network is public or not, so we have to test
IPSocket socket = new IPSocket(vm.getIpAddress(), 22);
System.err.printf("testing socket %s%n", socket);
System.err.printf("testing ssh %s%n", socket);
checkSSH(socket);
} else {
System.err.printf("skipping ssh %s, as private%n", vm.getIpAddress());
}
}
protected void checkSSH(IPSocket socket) {
socketTester.apply(socket);
SshClient client = sshFactory.create(socket, new Credentials(username, password));
try {
client.connect();
ExecResponse exec = client.exec("echo hello");
System.out.println(exec);
assertEquals(exec.getOutput().trim(), "hello");
} finally {
if (client != null)
client.disconnect();
}
}
@AfterGroups(groups = "live")
protected void tearDown() {
if (vm != null) {
assert taskTester.apply(client.removeVMFromVDC(billingSiteId, vpdcId, vm.getId()).getId()) : vm;
}
super.tearDown();
}
}

View File

@ -0,0 +1 @@
<vApp:VApp xmlns:vApp="http://www.vmware.com/vcloud/v0.8" xmlns:common="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" href="" name="DemoHost-1" type="application/vnd.vmware.vcloud.vApp+xml"><ovf:OperatingSystemSection ovf:id="80"><ovf:Info>Specifies the operating system installed</ovf:Info><ovf:Description>Red Hat Enterprise Linux 5.x 64bit</ovf:Description></ovf:OperatingSystemSection><ovf:VirtualHardwareSection><ovf:Info>Virtual Hardware</ovf:Info><ovf:System><vssd:Description>Virtual Hardware Family</vssd:Description><vssd:ElementName>DemoHost-1</vssd:ElementName><vssd:InstanceID>1</vssd:InstanceID><vssd:VirtualSystemIdentifier>DemoHost-1</vssd:VirtualSystemIdentifier></ovf:System><ovf:Item><rasd:AllocationUnits>3 GHz</rasd:AllocationUnits><rasd:Description>Number of Virtual CPUs</rasd:Description><rasd:ElementName>1 CPU</rasd:ElementName><rasd:InstanceID>1</rasd:InstanceID><rasd:ResourceType>3</rasd:ResourceType><rasd:VirtualQuantity>1</rasd:VirtualQuantity></ovf:Item><ovf:Item><rasd:AllocationUnits>Gigabytes</rasd:AllocationUnits><rasd:Description>Memory Size</rasd:Description><rasd:ElementName>Memory</rasd:ElementName><rasd:InstanceID>2</rasd:InstanceID><rasd:ResourceType>4</rasd:ResourceType><rasd:VirtualQuantity>1</rasd:VirtualQuantity></ovf:Item><ovf:Item><rasd:Caption>false</rasd:Caption><rasd:Connection>VM Tier01</rasd:Connection><rasd:ElementName>Network</rasd:ElementName><rasd:InstanceID>3</rasd:InstanceID><rasd:ResourceType>10</rasd:ResourceType><rasd:VirtualQuantity>1</rasd:VirtualQuantity></ovf:Item><ovf:Item><rasd:AllocationUnits>Gigabytes</rasd:AllocationUnits><rasd:Caption/><rasd:Description>Hard Disk</rasd:Description><rasd:ElementName>/</rasd:ElementName><rasd:HostResource>boot</rasd:HostResource><rasd:InstanceID>4</rasd:InstanceID><rasd:ResourceType>27</rasd:ResourceType><rasd:VirtualQuantity>10</rasd:VirtualQuantity></ovf:Item></ovf:VirtualHardwareSection></vApp:VApp>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<vApp:Network xmlns:common="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:vApp="http://www.vmware.com/vcloud/v0.8"
xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"
xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData"
xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" name="VM Tier01"
type="application/vnd.vmware.vcloud.network+xml">
<vApp:Configuration>
<vApp:Gateway>1.1.1.1</vApp:Gateway>
<vApp:Netmask>2.2.2.2</vApp:Netmask>
</vApp:Configuration>
<vApp:Features>
<vApp:FenceMode>allowInOut</vApp:FenceMode>
<vApp:Nat>
<vApp:NatRule internalIP="3.3.3.3" externalIP="4.4.4.4"/>
<vApp:NatRule internalIP="3.3.3.4" externalIP="4.4.4.5"/>
</vApp:Nat>
</vApp:Features>
</vApp:Network>