Merge pull request #171 from jsonking/695-1

Issue 695 - Fridays Changes
This commit is contained in:
Adrian Cole 2011-11-18 09:27:03 -08:00
commit 563eecc124
36 changed files with 514 additions and 129 deletions

View File

@ -20,6 +20,7 @@ package org.jclouds.tmrk.enterprisecloud;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.tmrk.enterprisecloud.features.TaskAsyncClient;
import org.jclouds.tmrk.enterprisecloud.features.VirtualMachineAsyncClient;
/**
* Provides asynchronous access to TerremarkEnterpriseCloud via their REST API.
@ -38,4 +39,10 @@ public interface TerremarkEnterpriseCloudAsyncClient {
*/
@Delegate
TaskAsyncClient getTaskClient();
/**
* Provides asynchronous access to VirtualMachine features.
*/
@Delegate
VirtualMachineAsyncClient getVirtualMachineClient();
}

View File

@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.tmrk.enterprisecloud.features.TaskClient;
import org.jclouds.tmrk.enterprisecloud.features.VirtualMachineClient;
/**
* Provides synchronous access to TerremarkEnterpriseCloud.
@ -42,4 +43,10 @@ public interface TerremarkEnterpriseCloudClient {
*/
@Delegate
TaskClient getTaskClient();
/**
* Provides synchronous access to VirtualMachine features.
*/
@Delegate
VirtualMachineClient getVirtualMachineClient();
}

View File

@ -33,6 +33,8 @@ import org.jclouds.tmrk.enterprisecloud.TerremarkEnterpriseCloudAsyncClient;
import org.jclouds.tmrk.enterprisecloud.TerremarkEnterpriseCloudClient;
import org.jclouds.tmrk.enterprisecloud.features.TaskAsyncClient;
import org.jclouds.tmrk.enterprisecloud.features.TaskClient;
import org.jclouds.tmrk.enterprisecloud.features.VirtualMachineAsyncClient;
import org.jclouds.tmrk.enterprisecloud.features.VirtualMachineClient;
import org.jclouds.tmrk.enterprisecloud.handlers.TerremarkEnterpriseCloudErrorHandler;
import com.google.common.collect.ImmutableMap;
@ -47,8 +49,9 @@ import com.google.common.collect.ImmutableMap;
public class TerremarkEnterpriseCloudRestClientModule extends
RestClientModule<TerremarkEnterpriseCloudClient, TerremarkEnterpriseCloudAsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(TaskClient.class, TaskAsyncClient.class)//
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
.put(TaskClient.class, TaskAsyncClient.class)
.put(VirtualMachineClient.class, VirtualMachineAsyncClient.class)
.build();
public TerremarkEnterpriseCloudRestClientModule() {

View File

@ -18,13 +18,6 @@
*/
package org.jclouds.tmrk.enterprisecloud.domain;
import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseNamedResource;
import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource;
@ -32,14 +25,18 @@ import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlRootElement;
import java.net.URI;
import java.util.Map;
import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static com.google.common.base.Preconditions.checkNotNull;
/**
*
* <xs:complexType name="Action">
* @author Adrian Cole
*
*/
@XmlRootElement(name = "Action")
public class Action extends BaseNamedResource<Action> {
@XmlEnum
public static enum ActionDisabled {

View File

@ -21,23 +21,24 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import com.google.common.collect.Sets;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Wraps individual Action elements.
* Needed because parsing is done with JAXB and it does not handle Generic collections
* @author Jason King
*/
@XmlRootElement(name = "Actions")
public class Actions {
private LinkedHashSet<Action> actions = Sets.newLinkedHashSet();
@XmlElement(name = "Action")
void setAction(Action action) {
checkNotNull(action,"action");
this.actions.add(action);
}

View File

@ -21,23 +21,30 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.net.URI;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* <xs:complexType name="AssignedIpAddresses">
* @author Jason King
*/
@XmlRootElement(name="AssignedIpAddresses")
public class AssignedIpAddresses extends BaseResource<AssignedIpAddresses> {
//TODO builder stuff
//TODO links
@XmlElement(name = "Actions", required = true)
private Actions actions;
private Actions actions = new Actions();
@XmlElement(name = "Networks", required = true)
private DeviceNetworks networks;
private DeviceNetworks networks = new DeviceNetworks();
public AssignedIpAddresses(URI href, String type, Actions actions, DeviceNetworks networks) {
super(href, type);
checkNotNull(actions,"actions");
checkNotNull(networks,"networks");
}
protected AssignedIpAddresses() {

View File

@ -25,7 +25,11 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.util.Preconditions2.checkNotEmpty;
/**
* <xs:complexType name="DeviceIps">
* Wraps individual IpAddresses
* @author Jason King
*/
@ -39,6 +43,8 @@ public class DeviceIps {
@XmlElement(name = "IpAddress")
void setIpAddress(String ipAddress) {
checkNotNull(ipAddress,"ipAddress");
checkNotEmpty(ipAddress, "ipAddress");
this.ipAddresses.add(ipAddress);
}

View File

@ -24,12 +24,13 @@ import javax.xml.bind.annotation.XmlElement;
/**
* Container for DeviceIps (ipAddresses)
* <xs:complexType name="DeviceNetwork">
* @author Jason King
*/
public class DeviceNetwork extends BaseNamedResource<DeviceNetwork> {
@XmlElement(name = "IpAddresses")
private DeviceIps ipAddresses;
private DeviceIps ipAddresses = new DeviceIps();
protected DeviceNetwork() {
//For JAXB

View File

@ -25,8 +25,11 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Container for DeviceNetwork items
* <xs:complexType name="DeviceNetworks">
* @author Jason King
*/
public class DeviceNetworks {
@ -39,6 +42,7 @@ public class DeviceNetworks {
@XmlElement(name = "Network")
void setDeviceNetwork(DeviceNetwork deviceNetwork) {
checkNotNull(deviceNetwork,"deviceNetwork");
this.deviceNetworks.add(deviceNetwork);
}

View File

@ -21,23 +21,25 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import com.google.common.collect.Sets;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Wraps individual Disk elements.
* Needed because parsing is done with JAXB and it does not handle Generic collections
* <xs:complexType name="Disks">
* @author Jason King
*/
@XmlRootElement(name = "Disks")
public class Disks {
private LinkedHashSet<VirtualDisk> disks = Sets.newLinkedHashSet();
@XmlElement(name = "Disk")
public void setVirtualDisk(VirtualDisk disk) {
checkNotNull(disk,"disk");
this.disks.add(disk);
}

View File

@ -20,12 +20,9 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseNamedResource;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @author Jason King
*/
@XmlRootElement(name = "Group")
public class Group extends BaseNamedResource<Group> {
public Group() {

View File

@ -18,11 +18,12 @@
*/
package org.jclouds.tmrk.enterprisecloud.domain;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.net.URI;
import java.util.Collections;
import java.util.Map;
@ -31,9 +32,9 @@ import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* <xs:complexType name="HardwareConfiguration">
* @author Jason King
*/
@XmlRootElement(name = "HardwareConfiguration")
public class HardwareConfiguration extends BaseResource<HardwareConfiguration> {
@SuppressWarnings("unchecked")
@ -51,18 +52,18 @@ public class HardwareConfiguration extends BaseResource<HardwareConfiguration> {
public static class Builder extends BaseResource.Builder<HardwareConfiguration> {
private Actions actions;
// TODO Links
private Set<Action> actions = Sets.newLinkedHashSet();
private int processorCount;
private Memory memory;
private Disks disks;
private Nics nics;
private Set<VirtualDisk> virtualDisks = Sets.newLinkedHashSet();
private Set<VirtualNic> virtualNics = Sets.newLinkedHashSet();
/**
* @see HardwareConfiguration#getActions
*/
public Builder actions(Set<Action> actions) {
this.actions = new Actions();
for(Action action:actions) this.actions.setAction(action);
this.actions = ImmutableSet.<Action> copyOf(checkNotNull(actions, "actions"));
return this;
}
@ -83,24 +84,25 @@ public class HardwareConfiguration extends BaseResource<HardwareConfiguration> {
}
/**
* @see HardwareConfiguration#getDisks
* @see HardwareConfiguration#getVirtualDisks
*/
public Builder disks(Disks disks) {
this.disks = disks;
public Builder disks(Set<VirtualDisk> virtualDisks) {
this.virtualDisks = ImmutableSet.<VirtualDisk> copyOf(checkNotNull(virtualDisks, "virtualDisks"));
return this;
}
/**
* @see HardwareConfiguration#getDisks
* @see HardwareConfiguration#getVirtualNics
*/
public Builder nics(Nics nics) {
this.nics = nics;
public Builder nics(Set<VirtualNic> virtualNics) {
this.virtualNics = ImmutableSet.<VirtualNic> copyOf(checkNotNull(virtualNics, "virtualNics"));
return this;
}
@Override
public HardwareConfiguration build() {
return new HardwareConfiguration(actions, processorCount, memory, disks, nics);
return new HardwareConfiguration(actions, processorCount, memory, virtualDisks, virtualNics);
}
/**
@ -139,13 +141,13 @@ public class HardwareConfiguration extends BaseResource<HardwareConfiguration> {
return fromResource(in).actions(in.getActions())
.processorCount(in.getProcessorCount())
.memory(in.getMemory())
.disks(in.getDisks())
.nics(in.getNics());
.disks(in.getVirtualDisks())
.nics(in.getVirtualNics());
}
}
@XmlElement(name = "Actions", required = false)
private Actions actions;
private Actions actions = new Actions();
@XmlElement(name = "ProcessorCount", required = true)
private int processorCount;
@ -154,17 +156,18 @@ public class HardwareConfiguration extends BaseResource<HardwareConfiguration> {
private Memory memory;
@XmlElement(name = "Disks", required = false)
private Disks disks;
private Disks virtualDisks = new Disks();
@XmlElement(name = "Nics", required = false)
private Nics nics;
private Nics virtualNics = new Nics();
public HardwareConfiguration(Set<Action> actions, int processorCount, @Nullable Memory memory, Set<VirtualDisk> virtualDisks, Set<VirtualNic> virtualNics) {
for( Action action: checkNotNull(actions, "actions")) this.actions.setAction(action);
for( VirtualDisk disk: checkNotNull(virtualDisks, "virtualDisks")) this.virtualDisks.setVirtualDisk(disk);
for( VirtualNic virtualNic: checkNotNull(virtualNics, "virtualNics")) this.virtualNics.setVirtualNic(virtualNic);
public HardwareConfiguration(@Nullable Actions actions, int processorCount, @Nullable Memory memory, @Nullable Disks disks, @Nullable Nics nics) {
this.actions = checkNotNull(actions, "actions");
this.processorCount = processorCount;
this.memory = memory;
this.disks = disks;
this.nics = nics;
}
protected HardwareConfiguration() {
@ -183,12 +186,12 @@ public class HardwareConfiguration extends BaseResource<HardwareConfiguration> {
return memory;
}
public Disks getDisks() {
return disks;
public Set<VirtualDisk> getVirtualDisks() {
return Collections.unmodifiableSet(virtualDisks.getVirtualDisks());
}
public Nics getNics() {
return nics;
public Set<VirtualNic> getVirtualNics() {
return Collections.unmodifiableSet(virtualNics.getVirtualNics());
}
@Override
@ -200,14 +203,11 @@ public class HardwareConfiguration extends BaseResource<HardwareConfiguration> {
HardwareConfiguration that = (HardwareConfiguration) o;
if (processorCount != that.processorCount) return false;
if (actions != null ? !actions.equals(that.actions) : that.actions != null)
return false;
if (disks != null ? !disks.equals(that.disks) : that.disks != null)
return false;
if (!actions.equals(that.actions)) return false;
if (!virtualDisks.equals(that.virtualDisks)) return false;
if (memory != null ? !memory.equals(that.memory) : that.memory != null)
return false;
if (nics != null ? !nics.equals(that.nics) : that.nics != null)
return false;
if (!virtualNics.equals(that.virtualNics)) return false;
return true;
}
@ -215,17 +215,17 @@ public class HardwareConfiguration extends BaseResource<HardwareConfiguration> {
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (actions != null ? actions.hashCode() : 0);
result = 31 * result + actions.hashCode();
result = 31 * result + processorCount;
result = 31 * result + (memory != null ? memory.hashCode() : 0);
result = 31 * result + (disks != null ? disks.hashCode() : 0);
result = 31 * result + (nics != null ? nics.hashCode() : 0);
result = 31 * result + virtualDisks.hashCode();
result = 31 * result + virtualNics.hashCode();
return result;
}
@Override
public String string() {
return super.string()+", actions="+actions+", processorCount="+processorCount+
", memory="+memory+", disks="+disks+", nics="+nics;
", memory="+memory+", disks="+ virtualDisks +", nics="+ virtualNics;
}
}

View File

@ -18,8 +18,9 @@
*/
package org.jclouds.tmrk.enterprisecloud.domain;
import org.jclouds.javax.annotation.Nullable;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Layout is a logical aggregation of virtual machines and physical devices defined by the organization.
@ -28,9 +29,9 @@ import javax.xml.bind.annotation.XmlRootElement;
* From the compute pool, only a subset is visible.
* To appear in a compute pool layout, virtual machines in the rows and groups must be allocated from the compute pool.
* As physical devices are not allocated from the compute pool, they do not appear on compute pool layouts.
* <xs:complexType name="LayoutReference">
* @author Jason King
*/
@XmlRootElement(name = "Layout")
public class Layout {
@XmlElement(name = "Group")
private Group group;
@ -38,7 +39,7 @@ public class Layout {
@XmlElement(name = "Row")
private Row row;
public Layout(Group group, Row row) {
public Layout(@Nullable Group group, @Nullable Row row) {
this.group = group;
this.row = row;
}

View File

@ -18,22 +18,22 @@
*/
package org.jclouds.tmrk.enterprisecloud.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseNamedResource;
import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import java.net.URI;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
*
* <xs:complexType name="Link">
* @author Adrian Cole
*
*/
@XmlRootElement(name = "Link")
public class Link extends BaseNamedResource<Link> {
@XmlEnum
public static enum Relationship {

View File

@ -21,7 +21,6 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import com.google.common.collect.Sets;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
@ -31,7 +30,6 @@ import java.util.Set;
* Needed because parsing is done with JAXB and it does not handle Generic collections
* @author Jason King
*/
@XmlRootElement(name = "Links")
public class Links {
private LinkedHashSet<Link> links = Sets.newLinkedHashSet();

View File

@ -20,12 +20,9 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import org.jclouds.tmrk.enterprisecloud.domain.internal.ResourceCapacity;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @author Jason King
*/
@XmlRootElement(name = "Memory")
public class Memory extends ResourceCapacity<Memory> {
@SuppressWarnings("unchecked")

View File

@ -25,18 +25,16 @@ import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseResource;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlRootElement;
import java.net.URI;
import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
/**
*
* <xs:complexType name="NetworkReference">
* @author Jason King
*
*/
@XmlRootElement(name = "Network")
public class NetworkReference extends BaseNamedResource<NetworkReference> {
@XmlEnum
public static enum NetworkType {
@ -135,7 +133,7 @@ public class NetworkReference extends BaseNamedResource<NetworkReference> {
@XmlElement(name = "NetworkType")
private NetworkType networkType;
public NetworkReference(URI href, String type, String name, NetworkType networkType) {
public NetworkReference(URI href, String type, String name,@Nullable NetworkType networkType) {
super(href, type, name);
this.networkType = networkType;
}

View File

@ -21,7 +21,6 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import com.google.common.collect.Sets;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
@ -29,9 +28,9 @@ import java.util.Set;
/**
* Wraps individual VirtualNic elements.
* Needed because parsing is done with JAXB and it does not handle Generic collections
* <xs:complexType name="Nics">
* @author Jason King
*/
@XmlRootElement(name = "Nics")
public class Nics {
private LinkedHashSet<VirtualNic> nics = Sets.newLinkedHashSet();

View File

@ -25,12 +25,14 @@ import java.net.URI;
import java.util.Map;
/**
*
* <xs:complexType name="OperatingSystem">
* @author Jason King
*
*/
public class OperatingSystem extends BaseNamedResource<OperatingSystem> {
//TODO There are other fields
@SuppressWarnings("unchecked")
public static Builder builder() {
return new Builder();

View File

@ -20,12 +20,9 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import org.jclouds.tmrk.enterprisecloud.domain.internal.BaseNamedResource;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @author Jason King
*/
@XmlRootElement(name = "Row")
public class Row extends BaseNamedResource<Row> {
public Row() {
//For JAXB

View File

@ -20,12 +20,9 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import org.jclouds.tmrk.enterprisecloud.domain.internal.ResourceCapacity;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @author Jason King
*/
@XmlRootElement(name = "Size")
public class Size extends ResourceCapacity<Size> {
@SuppressWarnings("unchecked")

View File

@ -35,7 +35,7 @@ import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* <xs:complexType name="Task">
* @author Adrian Cole
*
*/
@ -110,6 +110,7 @@ public class Task extends BaseResource<Task> {
}
public static class Builder extends BaseResource.Builder<Task> {
//TODO There are additional fields
protected String operation;
protected Status status;
protected NamedResource impactedItem;

View File

@ -26,18 +26,22 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Wraps individual Task elements.
* Needed because parsing is done with JAXB and it does not handle Generic collections
* <xs:complexType name="Tasks">
* @author Jason King
*/
@XmlRootElement(name = "Tasks")
public class Tasks {
//TODO: There is a total count field
private LinkedHashSet<Task> tasks = Sets.newLinkedHashSet();
@XmlElement(name = "Task")
public void setTask(Task task) {
checkNotNull(task,"task");
tasks.add(task);
}

View File

@ -25,6 +25,7 @@ import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
/**
* <xs:simpleType name="ToolsStatus">
* @author Jason King
*/
@XmlEnum

View File

@ -21,12 +21,11 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import org.jclouds.javax.annotation.Nullable;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* <xs:complexType name="VirtualDisk">
* @author Jason King
*/
@XmlRootElement(name = "Disk")
public class VirtualDisk {
@SuppressWarnings("unchecked")

View File

@ -36,7 +36,7 @@ import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static com.google.common.base.Preconditions.checkNotNull;
/**
*
* <xs:complexType name="VirtualMachine">
* @author Jason King
*
*/
@ -57,9 +57,10 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
}
public static class Builder extends BaseNamedResource.Builder<VirtualMachine> {
private Links links;
private Actions actions;
private Tasks tasks;
//TODO There are some more fields
private Links links = new Links();
private Actions actions = new Actions();
private Tasks tasks = new Tasks();
private String description;
private VirtualMachineStatus status;
@ -70,13 +71,13 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
private boolean customizationPending;
private OperatingSystem operatingSystem;
private HardwareConfiguration hardwareConfiguration;
private VirtualMachineIpAddresses ipAddresses;
private VirtualMachineIpAddresses ipAddresses = new VirtualMachineIpAddresses();
/**
* @see VirtualMachine#getLinks
*/
public Builder links(Set<Link> links) {
this.links = new Links();
checkNotNull(links,"links");
for(Link link:links) this.links.setLink(link);
return this;
}
@ -85,7 +86,7 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
* @see VirtualMachine#getActions
*/
public Builder actions(Set<Action> actions) {
this.actions = new Actions();
checkNotNull(actions,"actions");
for(Action action:actions) this.actions.setAction(action);
return this;
}
@ -94,7 +95,7 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
* @see VirtualMachine#getTasks
*/
public Builder tasks(Set<Task> tasks) {
this.tasks = new Tasks();
checkNotNull(tasks,"tasks");
for(Task task: tasks) this.tasks.setTask(task);
return this;
}
@ -184,7 +185,7 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
* @see VirtualMachine#getIpAddresses()
*/
public Builder ipAddresses(VirtualMachineIpAddresses ipAddresses) {
this.ipAddresses = ipAddresses;
this.ipAddresses = checkNotNull(ipAddresses,"ipAddresses");
return this;
}
@ -264,13 +265,13 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
}
@XmlElement(name = "Links", required = true)
private Links links;
private Links links = new Links();
@XmlElement(name = "Tasks", required = true)
private Tasks tasks;
private Tasks tasks = new Tasks();
@XmlElement(name = "Actions", required = true)
private Actions actions;
private Actions actions = new Actions();
@XmlElement(name = "Description", required = true)
private String description;
@ -300,7 +301,7 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
private HardwareConfiguration hardwareConfiguation;
@XmlElement(name = "IpAddresses", required = false)
private VirtualMachineIpAddresses ipAddresses;
private VirtualMachineIpAddresses ipAddresses = new VirtualMachineIpAddresses();
public VirtualMachine(URI href, String type, String name, Tasks tasks, Actions actions, Links links, String description, @Nullable Layout layout,
VirtualMachineStatus status, boolean poweredOn, @Nullable ToolsStatus toolsStatus, @Nullable VirtualMachineMediaStatus mediaStatus, boolean customizationPending,
@ -319,7 +320,7 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
this.customizationPending = customizationPending;
this.operatingSystem = operatingSystem;
this.hardwareConfiguation = hardwareConfiguration;
this.ipAddresses = ipAddresses;
this.ipAddresses = checkNotNull(ipAddresses, "ipAddresses");
}
protected VirtualMachine() {
@ -393,9 +394,6 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
return operatingSystem;
}
/**
* Is optional, so may return null
*/
public VirtualMachineIpAddresses getIpAddresses() {
return ipAddresses;
}
@ -411,11 +409,11 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
if (customizationPending != that.customizationPending) return false;
if (poweredOn != that.poweredOn) return false;
if (!actions.equals(that.actions)) return false;
if (!description.equals(that.description)) return false;
if (description != null ? !description.equals(that.description) : that.description != null)
return false;
if (hardwareConfiguation != null ? !hardwareConfiguation.equals(that.hardwareConfiguation) : that.hardwareConfiguation != null)
return false;
if (ipAddresses != null ? !ipAddresses.equals(that.ipAddresses) : that.ipAddresses != null)
return false;
if (!ipAddresses.equals(that.ipAddresses)) return false;
if (layout != null ? !layout.equals(that.layout) : that.layout != null)
return false;
if (!links.equals(that.links)) return false;
@ -435,16 +433,16 @@ public class VirtualMachine extends BaseNamedResource<VirtualMachine> {
result = 31 * result + links.hashCode();
result = 31 * result + tasks.hashCode();
result = 31 * result + actions.hashCode();
result = 31 * result + description.hashCode();
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + (layout != null ? layout.hashCode() : 0);
result = 31 * result + status.hashCode();
result = 31 * result + (status != null ? status.hashCode() : 0);
result = 31 * result + (poweredOn ? 1 : 0);
result = 31 * result + (toolsStatus != null ? toolsStatus.hashCode() : 0);
result = 31 * result + (mediaStatus != null ? mediaStatus.hashCode() : 0);
result = 31 * result + (customizationPending ? 1 : 0);
result = 31 * result + (operatingSystem != null ? operatingSystem.hashCode() : 0);
result = 31 * result + (hardwareConfiguation != null ? hardwareConfiguation.hashCode() : 0);
result = 31 * result + (ipAddresses != null ? ipAddresses.hashCode() : 0);
result = 31 * result + ipAddresses.hashCode();
return result;
}

View File

@ -27,12 +27,15 @@ import java.util.LinkedHashSet;
import java.util.Set;
/**
* <xs:complexType name="VirtualMachineIpAddresses">
* @author Jason King
*/
public class VirtualMachineIpAddresses {
//TODO There are more fields
@XmlElement(name = "AssignedIpAddresses")
private AssignedIpAddresses assignedIpAddresses;
private AssignedIpAddresses assignedIpAddresses = new AssignedIpAddresses();
protected VirtualMachineIpAddresses() {
// For JAXB

View File

@ -0,0 +1,69 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.tmrk.enterprisecloud.domain;
import com.google.common.collect.Sets;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Wraps individual VirtualMachine elements.
* Needed because parsing is done with JAXB and it does not handle Generic collections
* <xs:complexType name="VirtualMachines">
* @author Jason King
*/
@XmlRootElement(name="VirtualMachines")
public class VirtualMachines {
private LinkedHashSet<VirtualMachine> virtualMachines = Sets.newLinkedHashSet();
@XmlElement(name = "VirtualMachine")
void setVirtualMachine(VirtualMachine nic) {
this.virtualMachines.add(nic);
}
public Set<VirtualMachine> getVirtualMachines() {
return Collections.unmodifiableSet(virtualMachines);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
VirtualMachines vms1 = (VirtualMachines) o;
if (!virtualMachines.equals(vms1.virtualMachines)) return false;
return true;
}
@Override
public int hashCode() {
return virtualMachines.hashCode();
}
public String toString() {
return "["+ virtualMachines.toString()+"]";
}
}

View File

@ -21,12 +21,11 @@ package org.jclouds.tmrk.enterprisecloud.domain;
import org.jclouds.javax.annotation.Nullable;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* <xs:complexType name="VirtualNic">
* @author Jason King
*/
@XmlRootElement(name = "Nic")
public class VirtualNic {
@SuppressWarnings("unchecked")

View File

@ -25,7 +25,9 @@ import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.JAXBResponseParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.tmrk.enterprisecloud.domain.AssignedIpAddresses;
import org.jclouds.tmrk.enterprisecloud.domain.VirtualMachine;
import org.jclouds.tmrk.enterprisecloud.domain.VirtualMachines;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@ -46,6 +48,16 @@ import javax.ws.rs.PathParam;
@Headers(keys = "x-tmrk-version", values = "{jclouds.api-version}")
public interface VirtualMachineAsyncClient {
/**
* @see VirtualMachineClient#getVirtualMachines
*/
@GET
@Path("/virtualMachines/computePools/{id}")
@Consumes("application/vnd.tmrk.cloud.virtualMachine; type=collection")
@JAXBResponseParser
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<VirtualMachines> getVirtualMachines(@PathParam("id") long id);
/**
* @see VirtualMachineClient#getVirtualMachine
*/
@ -56,4 +68,14 @@ public interface VirtualMachineAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<VirtualMachine> getVirtualMachine(@PathParam("id") long id);
/**
* @see VirtualMachineClient#getVirtualMachine
*/
@GET
@Path("/virtualMachines/{id}/assignedIps")
@Consumes("application/vnd.tmrk.cloud.virtualMachineAssignedIps")
@JAXBResponseParser
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<AssignedIpAddresses> getAssignedIpAddresses(@PathParam("id") long id);
}

View File

@ -19,7 +19,9 @@
package org.jclouds.tmrk.enterprisecloud.features;
import org.jclouds.concurrent.Timeout;
import org.jclouds.tmrk.enterprisecloud.domain.AssignedIpAddresses;
import org.jclouds.tmrk.enterprisecloud.domain.VirtualMachine;
import org.jclouds.tmrk.enterprisecloud.domain.VirtualMachines;
import java.util.concurrent.TimeUnit;
@ -36,12 +38,27 @@ import java.util.concurrent.TimeUnit;
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
public interface VirtualMachineClient {
/**
* returns information regarding virtual machines defined in a compute pool
* @param id the i of the compute pool
* @return the virtual machines
*/
VirtualMachines getVirtualMachines(long id);
/**
* The Get Virtual Machines by ID call returns information regarding a
* specified virtual machine defined in an environment.
*
* @param id the id of the virtual machine
* @return the virtual Machine or null if not found
*/
VirtualMachine getVirtualMachine(long id);
/**
* The Get Virtual Machines Assigned IP Addresses call returns information
* regarding the IP addresses assigned to a specified virtual machine in a compute pool.
* @param id the id of the virtual machine
* @return the assigned ip addresses
*/
AssignedIpAddresses getAssignedIpAddresses(long id);
}

View File

@ -48,7 +48,34 @@ public class VirtualMachineAsyncClientTest extends BaseTerremarkEnterpriseCloudA
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testGetVirtualMachines() throws SecurityException, NoSuchMethodException, IOException {
Method method = VirtualMachineAsyncClient.class.getMethod("getVirtualMachines", long.class);
HttpRequest httpRequest = processor.createRequest(method,567);
assertRequestLineEquals(httpRequest, "GET https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/virtualMachines/computePools/567 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/vnd.tmrk.cloud.virtualMachine; type=collection\nx-tmrk-version: 2011-07-01\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testGetAssignedIpAddresses() throws SecurityException, NoSuchMethodException, IOException {
Method method = VirtualMachineAsyncClient.class.getMethod("getAssignedIpAddresses", long.class);
HttpRequest httpRequest = processor.createRequest(method,1);
assertRequestLineEquals(httpRequest, "GET https://services-beta.enterprisecloud.terremark.com/cloudapi/ecloud/virtualMachines/1/assignedIps HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/vnd.tmrk.cloud.virtualMachineAssignedIps\nx-tmrk-version: 2011-07-01\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseXMLWithJAXB.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override

View File

@ -0,0 +1,88 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.tmrk.enterprisecloud.features;
import com.google.common.collect.Iterables;
import org.jclouds.tmrk.enterprisecloud.domain.AssignedIpAddresses;
import org.jclouds.tmrk.enterprisecloud.domain.DeviceNetwork;
import org.jclouds.tmrk.enterprisecloud.domain.VirtualMachine;
import org.jclouds.tmrk.enterprisecloud.domain.VirtualMachines;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import java.net.URI;
import java.util.Set;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
/**
* Tests behavior of {@code VirtualMachineClient}
*
* @author Jason King
*/
@Test(groups = "live", testName = "VirtualMachineClientLiveTest")
public class VirtualMachineClientLiveTest extends BaseTerremarkEnterpriseCloudClientLiveTest {
@BeforeGroups(groups = { "live" })
public void setupClient() {
super.setupClient();
client = context.getApi().getVirtualMachineClient();
}
private VirtualMachineClient client;
@Test
public void testGetVirtualMachines() throws Exception {
// TODO: don't hard-code id
VirtualMachines virtualMachines = client.getVirtualMachines(89);
for( VirtualMachine vm : virtualMachines.getVirtualMachines()) {
VirtualMachine virtualMachine = client.getVirtualMachine(parse(vm.getHref()));
assert null != virtualMachine;
assertEquals(virtualMachine.getStatus(),VirtualMachine.VirtualMachineStatus.DEPLOYED);
}
}
@Test
public void testGetVirtualMachine() throws Exception {
// TODO: don't hard-code id
VirtualMachine virtualMachine = client.getVirtualMachine(5504);
assert null != virtualMachine;
assertEquals(virtualMachine.getStatus(),VirtualMachine.VirtualMachineStatus.DEPLOYED);
}
@Test
public void testGetAssignedIpAddresses() throws Exception {
AssignedIpAddresses assignedIpAddresses = client.getAssignedIpAddresses(5504);
assert null != assignedIpAddresses;
DeviceNetwork network = Iterables.getOnlyElement(assignedIpAddresses.getNetworks().getDeviceNetworks());
Set<String> ipAddresses = network.getIpAddresses().getIpAddresses();
assertTrue(ipAddresses.size()>0, "vm has no assigned ip addresses");
}
// TODO: We are not supposed to parse the href's
// The alternative is to use URI's on the method calls.
// But this has the risk of exposing strings like "/virtualmachines/5504" and "/computepools/89" to users
// Also - would need to figure out how to configure the tests
// to add on the endpoint so that the @EndpointParam is converted into a proper request.
private long parse(URI uri) {
String path = uri.getPath();
path = path.substring(path.lastIndexOf("/")+1);
return Long.parseLong(path);
}
}

View File

@ -0,0 +1,119 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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.tmrk.enterprisecloud.xml;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Provides;
import org.jclouds.crypto.Crypto;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseXMLWithJAXB;
import org.jclouds.logging.config.NullLoggingModule;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.BaseRestClientTest;
import org.jclouds.rest.RestContextSpec;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.tmrk.enterprisecloud.domain.*;
import org.jclouds.tmrk.enterprisecloud.domain.VirtualMachine.VirtualMachineStatus;
import org.jclouds.tmrk.enterprisecloud.features.VirtualMachineAsyncClient;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import javax.inject.Named;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Set;
import static org.jclouds.io.Payloads.newInputStreamPayload;
import static org.jclouds.rest.RestContextFactory.contextSpec;
import static org.jclouds.rest.RestContextFactory.createContextBuilder;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
/**
* Tests behavior of JAXB parsing for AssignedIpAddresses
*
* @author Jason King
*/
@Test(groups = "unit", testName = "AssignedIpAddressesJAXBParsingTest")
public class AssignedIpAddressesJAXBParsingTest extends BaseRestClientTest {
private SimpleDateFormatDateService dateService;
@BeforeMethod
public void setUp() {
dateService = new SimpleDateFormatDateService();
}
@BeforeClass
void setupFactory() {
RestContextSpec<String, Integer> contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "userfoo",
"credentialFoo", String.class, Integer.class,
ImmutableSet.<Module> of(new MockModule(), new NullLoggingModule(), new AbstractModule() {
@Override
protected void configure() {}
@SuppressWarnings("unused")
@Provides
@Named("exception")
Set<String> exception() {
throw new AuthorizationException();
}
}));
injector = createContextBuilder(contextSpec).buildInjector();
parserFactory = injector.getInstance(ParseSax.Factory.class);
crypto = injector.getInstance(Crypto.class);
}
@Test
public void testParseAssignedIpAddressesWithJAXB() throws Exception {
Method method = VirtualMachineAsyncClient.class.getMethod("getAssignedIpAddresses", long.class);
HttpRequest request = factory(VirtualMachineAsyncClient.class).createRequest(method,1);
assertResponseParserClassEquals(method, request, ParseXMLWithJAXB.class);
Function<HttpResponse, AssignedIpAddresses> parser = (Function<HttpResponse, AssignedIpAddresses>) RestAnnotationProcessor
.createResponseParser(parserFactory, injector, method, request);
InputStream is = getClass().getResourceAsStream("/assignedIpAddresses.xml");
AssignedIpAddresses addresses = parser.apply(new HttpResponse(200, "ok", newInputStreamPayload(is)));
Assert.assertNotNull(addresses);
Set<DeviceNetwork> deviceNetworks = addresses.getNetworks().getDeviceNetworks();
assertEquals(1,deviceNetworks.size());
DeviceNetwork network = Iterables.getOnlyElement(deviceNetworks);
Set<String> ips = network.getIpAddresses().getIpAddresses();
assertEquals(2,ips.size());
assertTrue(ips.contains("10.146.204.98"));
assertTrue(ips.contains("10.146.204.99"));
}
}

View File

@ -20,6 +20,7 @@ package org.jclouds.tmrk.enterprisecloud.xml;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.google.inject.Provides;
@ -38,7 +39,6 @@ import org.jclouds.tmrk.enterprisecloud.domain.*;
import org.jclouds.tmrk.enterprisecloud.domain.VirtualMachine.VirtualMachineStatus;
import org.jclouds.tmrk.enterprisecloud.features.VirtualMachineAsyncClient;
import org.testng.Assert;
import org.testng.AssertJUnit;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@ -142,18 +142,16 @@ public class VirtualMachineJAXBParsingTest extends BaseRestClientTest {
assertEquals(1,hardwareConfiguration.getProcessorCount());
Memory memory = Memory.builder().value(384).unit("MB").build();
assertEquals(memory,hardwareConfiguration.getMemory());
assertDisks(hardwareConfiguration.getDisks());
assertNics(hardwareConfiguration.getNics().getVirtualNics());
assertDisks(hardwareConfiguration.getVirtualDisks());
assertNics(hardwareConfiguration.getVirtualNics());
}
private void assertDisks(Disks disks) {
private void assertDisks(Set<VirtualDisk> disks) {
VirtualDisk disk = VirtualDisk.builder().index(0).name("Hard Disk 1")
.size(Size.builder().value(10).unit("GB").build())
.build();
Disks expectedDisks = new Disks();
expectedDisks.setVirtualDisk(disk);
assertEquals(expectedDisks, disks);
assertEquals(ImmutableSet.of(disk), disks);
}
@ -182,7 +180,7 @@ public class VirtualMachineJAXBParsingTest extends BaseRestClientTest {
Assert.assertNotNull(assignedIpAddresses);
Set<DeviceNetwork> deviceNetworks = assignedIpAddresses.getNetworks().getDeviceNetworks();
assertEquals(1,deviceNetworks.size());
DeviceNetwork network = deviceNetworks.iterator().next(); //todo use guava instead.
DeviceNetwork network = Iterables.getOnlyElement(deviceNetworks);
Set<String> ips = network.getIpAddresses().getIpAddresses();
assertEquals(2,ips.size());
assertTrue(ips.contains("10.146.204.67"));

View File

@ -0,0 +1,19 @@
<AssignedIpAddresses href="/cloudapi/ecloud/virtualmachines/5504/assignedips"
type="application/vnd.tmrk.cloud.virtualMachineAssignedIps"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Actions>
<Action href="/cloudapi/ecloud/virtualmachines/5504/assignedips"
name="edit"
type="application/vnd.tmrk.cloud.virtualMachineAssignedIps"/>
</Actions>
<Networks>
<Network href="/cloudapi/ecloud/networks/3936"
name="10.146.204.64/28 (INT_202)"
type="application/vnd.tmrk.cloud.network">
<IpAddresses>
<IpAddress>10.146.204.98</IpAddress>
<IpAddress>10.146.204.99</IpAddress>
</IpAddresses>
</Network>
</Networks>
</AssignedIpAddresses>