diff --git a/sandbox/cloudsigma/pom.xml b/sandbox/cloudsigma/pom.xml new file mode 100644 index 0000000000..0b6be3bd0d --- /dev/null +++ b/sandbox/cloudsigma/pom.xml @@ -0,0 +1,140 @@ + + + + 4.0.0 + + org.jclouds + jclouds-project + 1.0-SNAPSHOT + ../../project/pom.xml + + org.jclouds + jclouds-cloudsigma + jclouds cloudsigma core + jclouds components to access cloudsigma + + + + + jclouds-googlecode-deploy + http://jclouds.googlecode.com/svn/repo + + + jclouds-rimu-snapshots-nexus + https://oss.sonatype.org/content/repositories/snapshots + + true + + + + + + + trmkrun-ccc,test.trmk-924 + https://api.cloudsigma.com + 1.0 + FIXME + FIXME + + + + ${project.groupId} + jclouds-elasticstack + ${project.version} + + + ${project.groupId} + jclouds-core + ${project.version} + test-jar + test + + + ${project.groupId} + jclouds-elasticstack + ${project.version} + test-jar + test + + + log4j + log4j + 1.2.14 + test + + + ${project.groupId} + jclouds-log4j + ${project.version} + test + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration + integration-test + + test + + + + + test.cloudsigma.endpoint + ${test.cloudsigma.endpoint} + + + test.cloudsigma.apiversion + ${test.cloudsigma.apiversion} + + + test.cloudsigma.identity + ${test.cloudsigma.identity} + + + test.cloudsigma.credential + ${test.cloudsigma.credential} + + + jclouds.compute.blacklist-nodes + ${jclouds.compute.blacklist-nodes} + + + + + + + + + + + diff --git a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/config/CloudSigmaRestClientModule.java b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/config/CloudSigmaRestClientModule.java index 453362e8ae..0a0d4509d8 100644 --- a/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/config/CloudSigmaRestClientModule.java +++ b/sandbox/cloudsigma/src/main/java/org/jclouds/cloudsigma/config/CloudSigmaRestClientModule.java @@ -19,14 +19,20 @@ package org.jclouds.cloudsigma.config; +import java.util.List; import java.util.Map; +import java.util.Set; import org.jclouds.cloudsigma.CloudSigmaAsyncClient; import org.jclouds.cloudsigma.CloudSigmaClient; import org.jclouds.cloudsigma.functions.CreateDriveRequestToMap; import org.jclouds.cloudsigma.functions.DriveDataToMap; import org.jclouds.elasticstack.domain.CreateDriveRequest; +import org.jclouds.elasticstack.domain.Device; import org.jclouds.elasticstack.domain.DriveData; +import org.jclouds.elasticstack.domain.NIC; +import org.jclouds.elasticstack.functions.MapToDevices; +import org.jclouds.elasticstack.functions.MapToNICs; import org.jclouds.elasticstack.handlers.ElasticStackErrorHandler; import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.RequiresHttp; @@ -66,6 +72,10 @@ public class CloudSigmaRestClientModule extends RestClientModule>>() { }).to(DriveDataToMap.class); + bind(new TypeLiteral, List>>() { + }).to(MapToNICs.class); + bind(new TypeLiteral, Set>>() { + }).to(MapToDevices.class); } @Override diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackAsyncClient.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackAsyncClient.java index 193b155b72..e5f72ec460 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackAsyncClient.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackAsyncClient.java @@ -33,8 +33,11 @@ import org.jclouds.elasticstack.binders.BindDriveDataToPlainTextString; import org.jclouds.elasticstack.domain.CreateDriveRequest; import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveInfo; +import org.jclouds.elasticstack.domain.ServerInfo; import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; +import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToServerInfo; import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet; +import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet; import org.jclouds.elasticstack.functions.SplitNewlines; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.rest.annotations.BinderParam; @@ -58,6 +61,31 @@ import com.google.common.util.concurrent.ListenableFuture; @Consumes(MediaType.TEXT_PLAIN) public interface CommonElasticStackAsyncClient { + /** + * @see ElasticStackClient#listServers() + */ + @GET + @Path("/servers/list") + @ResponseParser(SplitNewlines.class) + ListenableFuture> listServers(); + + /** + * @see ElasticStackClient#listServerInfo() + */ + @GET + @Path("/servers/info") + @ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class) + ListenableFuture> listServerInfo(); + + /** + * @see ElasticStackClient#getServerInfo + */ + @GET + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class) + @Path("/servers/{uuid}/info") + ListenableFuture getServerInfo(@PathParam("uuid") String uuid); + /** * @see ElasticStackClient#listDrives() */ diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackClient.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackClient.java index 0f0acad24f..081c9979d0 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackClient.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/CommonElasticStackClient.java @@ -26,6 +26,7 @@ import org.jclouds.concurrent.Timeout; import org.jclouds.elasticstack.domain.CreateDriveRequest; import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveInfo; +import org.jclouds.elasticstack.domain.ServerInfo; /** * Provides synchronous access to elasticstack. @@ -37,6 +38,27 @@ import org.jclouds.elasticstack.domain.DriveInfo; */ @Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) public interface CommonElasticStackClient { + /** + * list of server uuids in your account + * + * @return or empty set if no servers are found + */ + Set listServers(); + + /** + * Get all servers info + * + * @return or empty set if no servers are found + */ + Set listServerInfo(); + + /** + * @param uuid + * what to get + * @return null, if not found + */ + ServerInfo getServerInfo(String uuid); + /** * list of drive uuids in your account * @@ -86,5 +108,4 @@ public interface CommonElasticStackClient { */ void destroyDrive(String uuid); - } diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/config/ElasticStackRestClientModule.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/config/ElasticStackRestClientModule.java index d8def53140..92e778fa46 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/config/ElasticStackRestClientModule.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/config/ElasticStackRestClientModule.java @@ -19,14 +19,20 @@ package org.jclouds.elasticstack.config; +import java.util.List; import java.util.Map; +import java.util.Set; import org.jclouds.elasticstack.ElasticStackAsyncClient; import org.jclouds.elasticstack.ElasticStackClient; import org.jclouds.elasticstack.domain.CreateDriveRequest; +import org.jclouds.elasticstack.domain.Device; import org.jclouds.elasticstack.domain.DriveData; +import org.jclouds.elasticstack.domain.NIC; import org.jclouds.elasticstack.functions.CreateDriveRequestToMap; import org.jclouds.elasticstack.functions.DriveDataToMap; +import org.jclouds.elasticstack.functions.MapToDevices; +import org.jclouds.elasticstack.functions.MapToNICs; import org.jclouds.elasticstack.handlers.ElasticStackErrorHandler; import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.RequiresHttp; @@ -59,6 +65,10 @@ public class ElasticStackRestClientModule extends RestClientModule>>() { }).to(DriveDataToMap.class); + bind(new TypeLiteral, List>>() { + }).to(MapToNICs.class); + bind(new TypeLiteral, Set>>() { + }).to(MapToDevices.class); } @Override diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/BlockDevice.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/BlockDevice.java index 757732c2f3..661377fe6a 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/BlockDevice.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/BlockDevice.java @@ -26,11 +26,25 @@ import static com.google.common.base.Preconditions.checkArgument; * @author Adrian Cole */ public class BlockDevice extends Device { + public static class Builder extends Device.Builder { + private final int index; - private final char index; + public Builder(int index) { + this.index = index; + } - public BlockDevice(String driveUuid, MediaType mediaType, char index) { - super(driveUuid, mediaType); + @Override + public Device build() { + return new BlockDevice(uuid, mediaType, index, readBytes, readRequests, writeBytes, writeRequests); + } + + } + + private final int index; + + public BlockDevice(String driveUuid, MediaType mediaType, int index, long readBytes, long readRequests, + long writeBytes, long writeRequests) { + super(driveUuid, mediaType, readBytes, readRequests, writeBytes, writeRequests); checkArgument(index >= 0 && index < 8, "index must be between 0 and 7"); this.index = index; } @@ -62,7 +76,7 @@ public class BlockDevice extends Device { return String.format("block:%d", index); } - public char getIndex() { + public int getIndex() { return index; } diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Device.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Device.java index 3085647581..8216e00db0 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Device.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Device.java @@ -26,12 +26,62 @@ import static com.google.common.base.Preconditions.checkNotNull; * @author Adrian Cole */ public abstract class Device { + public static abstract class Builder { + protected String uuid; + protected MediaType mediaType = MediaType.DISK; + protected long readBytes; + protected long readRequests; + protected long writeBytes; + protected long writeRequests; + + public Builder mediaType(MediaType mediaType) { + this.mediaType = mediaType; + return this; + } + + public Builder readBytes(long readBytes) { + this.readBytes = readBytes; + return this; + } + + public Builder readRequests(long readRequests) { + this.readRequests = readRequests; + return this; + } + + public Builder writeBytes(long writeBytes) { + this.writeBytes = writeBytes; + return this; + } + + public Builder writeRequests(long writeRequests) { + this.writeRequests = writeRequests; + return this; + } + + public Builder uuid(String uuid) { + this.uuid = uuid; + return this; + } + + public abstract Device build(); + } + protected final String driveUuid; protected final MediaType mediaType; + protected final long readBytes; + protected final long readRequests; + protected final long writeBytes; + protected final long writeRequests; - public Device(String driveUuid, MediaType mediaType) { + public Device(String driveUuid, MediaType mediaType, long readBytes, long readRequests, long writeBytes, + long writeRequests) { this.driveUuid = checkNotNull(driveUuid, "driveUuid"); this.mediaType = checkNotNull(mediaType, "mediaType"); + this.readBytes = readBytes; + this.readRequests = readRequests; + this.writeBytes = writeBytes; + this.writeRequests = writeRequests; } /** @@ -56,12 +106,48 @@ public abstract class Device { return mediaType; } + /** + * + * @return Cumulative i/o byte/request count for each drive + */ + public long getReadBytes() { + return readBytes; + } + + /** + * + * @return Cumulative i/o byte/request count for each drive + */ + public long getReadRequests() { + return readRequests; + } + + /** + * + * @return Cumulative i/o byte/request count for each drive + */ + public long getWriteBytes() { + return writeBytes; + } + + /** + * + * @return Cumulative i/o byte/request count for each drive + */ + public long getWriteRequests() { + return writeRequests; + } + @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((driveUuid == null) ? 0 : driveUuid.hashCode()); result = prime * result + ((mediaType == null) ? 0 : mediaType.hashCode()); + result = prime * result + (int) (readBytes ^ (readBytes >>> 32)); + result = prime * result + (int) (readRequests ^ (readRequests >>> 32)); + result = prime * result + (int) (writeBytes ^ (writeBytes >>> 32)); + result = prime * result + (int) (writeRequests ^ (writeRequests >>> 32)); return result; } @@ -81,11 +167,20 @@ public abstract class Device { return false; if (mediaType != other.mediaType) return false; + if (readBytes != other.readBytes) + return false; + if (readRequests != other.readRequests) + return false; + if (writeBytes != other.writeBytes) + return false; + if (writeRequests != other.writeRequests) + return false; return true; } @Override public String toString() { - return "[driveUuid=" + driveUuid + ", mediaType=" + mediaType + "]"; + return "[driveUuid=" + driveUuid + ", mediaType=" + mediaType + ", readBytes=" + readBytes + ", readRequests=" + + readRequests + ", writeBytes=" + writeBytes + ", writeRequests=" + writeRequests + "]"; } } \ No newline at end of file diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/IDEDevice.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/IDEDevice.java index dda18b9f8b..651c467a2d 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/IDEDevice.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/IDEDevice.java @@ -26,12 +26,28 @@ import static com.google.common.base.Preconditions.checkArgument; * @author Adrian Cole */ public class IDEDevice extends Device { + public static class Builder extends Device.Builder { + private final int bus; + private final int unit; - private final char bus; - private final char unit; + public Builder(int bus, int unit) { + this.bus = bus; + this.unit = unit; + } - public IDEDevice(String driveUuid, MediaType mediaType, char bus, char unit) { - super(driveUuid, mediaType); + @Override + public Device build() { + return new IDEDevice(uuid, mediaType, bus, unit, readBytes, readRequests, writeBytes, writeRequests); + } + + } + + private final int bus; + private final int unit; + + public IDEDevice(String driveUuid, MediaType mediaType, int bus, int unit, long readBytes, long readRequests, + long writeBytes, long writeRequests) { + super(driveUuid, mediaType, readBytes, readRequests, writeBytes, writeRequests); checkArgument(bus == 0 || bus == 1, "bus must be 0 or 1"); checkArgument(unit == 0 || unit == 1, "unit must be 0 or 1"); this.bus = bus; @@ -68,11 +84,11 @@ public class IDEDevice extends Device { return String.format("ide:%d:%d", bus, unit); } - public char getBus() { + public int getBus() { return bus; } - public char getUnit() { + public int getUnit() { return unit; } diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/NIC.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/NIC.java index b08625786c..c553edd6de 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/NIC.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/NIC.java @@ -21,23 +21,66 @@ package org.jclouds.elasticstack.domain; import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Set; + import javax.annotation.Nullable; +import com.google.common.collect.ImmutableSet; + /** * * @author Adrian Cole */ public class NIC { + public static class Builder { + private String dhcp; + private Model model; + private String vlan; + private String mac; + private Set block = ImmutableSet.of(); + + public Builder dhcp(String dhcp) { + this.dhcp = dhcp; + return this; + } + + public Builder model(Model model) { + this.model = model; + return this; + } + + public Builder vlan(String vlan) { + this.vlan = vlan; + return this; + } + + public Builder mac(String mac) { + this.mac = mac; + return this; + } + + public Builder block(Iterable block) { + this.block = ImmutableSet.copyOf(checkNotNull(block, "block")); + return this; + } + + public NIC build() { + return new NIC(dhcp, model, vlan, mac, block); + } + } + private final String dhcp; private final Model model; private final String vlan; private final String mac; + private final Set block; - public NIC(@Nullable String dhcp, Model model, @Nullable String vlan, @Nullable String mac) { + public NIC(@Nullable String dhcp, Model model, @Nullable String vlan, @Nullable String mac, Iterable block) { this.dhcp = dhcp; this.model = checkNotNull(model, "model"); this.vlan = vlan; this.mac = mac; + this.block = ImmutableSet.copyOf(checkNotNull(block, "block")); } /** @@ -75,10 +118,16 @@ public class NIC { return mac; } + // TODO undocumented + public Set getBlock() { + return block; + } + @Override public int hashCode() { final int prime = 31; int result = 1; + result = prime * result + ((block == null) ? 0 : block.hashCode()); result = prime * result + ((dhcp == null) ? 0 : dhcp.hashCode()); result = prime * result + ((mac == null) ? 0 : mac.hashCode()); result = prime * result + ((model == null) ? 0 : model.hashCode()); @@ -95,6 +144,11 @@ public class NIC { if (getClass() != obj.getClass()) return false; NIC other = (NIC) obj; + if (block == null) { + if (other.block != null) + return false; + } else if (!block.equals(other.block)) + return false; if (dhcp == null) { if (other.dhcp != null) return false; @@ -117,6 +171,6 @@ public class NIC { @Override public String toString() { - return "[dhcp=" + dhcp + ", model=" + model + ", vlan=" + vlan + ", mac=" + mac + "]"; + return "[dhcp=" + dhcp + ", model=" + model + ", vlan=" + vlan + ", mac=" + mac + ", block=" + block + "]"; } } \ No newline at end of file diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/SCSIDevice.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/SCSIDevice.java index 56bd535294..665b7cdeb2 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/SCSIDevice.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/SCSIDevice.java @@ -26,12 +26,26 @@ import static com.google.common.base.Preconditions.checkArgument; * @author Adrian Cole */ public class SCSIDevice extends Device { + public static class Builder extends Device.Builder { + private final int unit; - private final char bus = 0; - private final char unit; + public Builder(int unit) { + this.unit = unit; + } - public SCSIDevice(String driveUuid, MediaType mediaType, char unit) { - super(driveUuid, mediaType); + @Override + public Device build() { + return new SCSIDevice(uuid, mediaType, unit, readBytes, readRequests, writeBytes, writeRequests); + } + + } + + private final int bus = 0; + private final int unit; + + public SCSIDevice(String driveUuid, MediaType mediaType, int unit, long readBytes, long readRequests, + long writeBytes, long writeRequests) { + super(driveUuid, mediaType, readBytes, readRequests, writeBytes, writeRequests); checkArgument(unit >= 0 && unit < 8, "unit must be between 0 and 7"); this.unit = unit; } @@ -61,11 +75,11 @@ public class SCSIDevice extends Device { return true; } - public char getBus() { + public int getBus() { return bus; } - public char getUnit() { + public int getUnit() { return unit; } diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Server.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/ServerInfo.java similarity index 68% rename from sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Server.java rename to sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/ServerInfo.java index ad85f45e84..9f0ecf2d64 100644 --- a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/Server.java +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/ServerInfo.java @@ -21,6 +21,7 @@ package org.jclouds.elasticstack.domain; import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; @@ -34,31 +35,15 @@ import com.google.common.collect.ImmutableSet; * * @author Adrian Cole */ -public class Server extends Item { - // - // user UUID - // status active|stopped - // cpu CPU - // smp SMP - // mem MEM - // bootDeviceIds UUID - // description DESCRIPTION - // ide:0:0 UUID - // ide:0:1 UUID - // ide:1:0 UUID - // ide:1:1 UUID - // nic:0:model NIC_0_MODEL - // nic:0:dhcp NIC_0_DHCP - // nic:1:model NIC_1_MODEL - // nic:1:vlan NIC_1_VLAN - // vnc:ip VNC_IP - // vnc:password VNC_PASS +public class ServerInfo extends Item { public static class Builder extends Item.Builder { protected int cpu; protected Integer smp; + protected ServerStatus status; protected int mem; protected boolean persistent; + protected Date started; protected Set devices = ImmutableSet.of(); protected Set bootDeviceIds = ImmutableSet.of(); protected List nics = ImmutableList.of(); @@ -66,6 +51,15 @@ public class Server extends Item { protected VNC vnc; // TODO undocumented protected String description; + protected long txPackets; + protected long tx; + protected long rxPackets; + protected long rx; + + public Builder status(ServerStatus status) { + this.status = status; + return this; + } public Builder cpu(int cpu) { this.cpu = cpu; @@ -87,6 +81,11 @@ public class Server extends Item { return this; } + public Builder started(Date started) { + this.started = started; + return this; + } + public Builder devices(Iterable devices) { this.devices = ImmutableSet.copyOf(checkNotNull(devices, "devices")); return this; @@ -117,6 +116,26 @@ public class Server extends Item { return this; } + public Builder txPackets(long txPackets) { + this.txPackets = txPackets; + return this; + } + + public Builder tx(long tx) { + this.tx = tx; + return this; + } + + public Builder rxPackets(long rxPackets) { + this.rxPackets = rxPackets; + return this; + } + + public Builder rx(long rx) { + this.rx = rx; + return this; + } + /** * {@inheritDoc} */ @@ -149,16 +168,19 @@ public class Server extends Item { return Builder.class.cast(super.userMetadata(userMetadata)); } - public Server build() { - return new Server(uuid, name, cpu, smp, mem, persistent, devices, tags, bootDeviceIds, userMetadata, nics, - user, vnc, description); + public ServerInfo build() { + return new ServerInfo(uuid, name, cpu, smp, mem, status, persistent, started, devices, tags, bootDeviceIds, + userMetadata, nics, user, vnc, description, tx, txPackets, rx, rxPackets); } } protected final int cpu; protected final Integer smp; protected final int mem; + protected final ServerStatus status; protected final boolean persistent; + @Nullable + protected final Date started; protected final Set devices; protected final Set bootDeviceIds; @Nullable @@ -167,21 +189,32 @@ public class Server extends Item { protected final VNC vnc; @Nullable private final String description; + protected final long txPackets; + protected final long tx; + protected final long rxPackets; + protected final long rx; - public Server(@Nullable String uuid, String name, int cpu, @Nullable Integer smp, int mem, boolean persistent, - Iterable devices, Iterable bootDeviceIds, Iterable tags, - Map userMetadata, Iterable nics, @Nullable String user, VNC vnc, String description) { + public ServerInfo(@Nullable String uuid, String name, int cpu, @Nullable Integer smp, int mem, ServerStatus status, + boolean persistent, @Nullable Date started, Iterable devices, + Iterable bootDeviceIds, Iterable tags, Map userMetadata, Iterable nics, + @Nullable String user, VNC vnc, String description, long tx, long txPackets, long rx, long rxPackets) { super(uuid, name, tags, userMetadata); this.cpu = cpu; this.smp = smp; this.mem = mem; + this.status = status; this.persistent = persistent; + this.started = started; this.devices = ImmutableSet.copyOf(checkNotNull(devices, "devices")); this.bootDeviceIds = ImmutableSet.copyOf(checkNotNull(bootDeviceIds, "bootDeviceIds")); this.nics = ImmutableList.copyOf(checkNotNull(nics, "nics")); this.user = user; this.vnc = checkNotNull(vnc, "vnc"); this.description = description; + this.txPackets = txPackets; + this.tx = tx; + this.rxPackets = rxPackets; + this.rx = rx; } /** @@ -208,6 +241,14 @@ public class Server extends Item { return mem; } + /** + * + * @return active | stopped | paused | dumped | dead + */ + public ServerStatus getStatus() { + return status; + } + /** * * @return 'true' means that server will revert to a 'stopped' status on server stop or shutdown, @@ -238,6 +279,31 @@ public class Server extends Item { return nics; } + // TODO undocumented + public Date getStarted() { + return started; + } + + // TODO undocumented + public long getTxPackets() { + return txPackets; + } + + // TODO undocumented + public long getTx() { + return tx; + } + + // TODO undocumented + public long getRxPackets() { + return rxPackets; + } + + // TODO undocumented + public long getRx() { + return rx; + } + // TODO undocumented /** * @@ -267,7 +333,13 @@ public class Server extends Item { result = prime * result + mem; result = prime * result + ((nics == null) ? 0 : nics.hashCode()); result = prime * result + (persistent ? 1231 : 1237); + result = prime * result + (int) (rx ^ (rx >>> 32)); + result = prime * result + (int) (rxPackets ^ (rxPackets >>> 32)); result = prime * result + ((smp == null) ? 0 : smp.hashCode()); + result = prime * result + ((started == null) ? 0 : started.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + result = prime * result + (int) (tx ^ (tx >>> 32)); + result = prime * result + (int) (txPackets ^ (txPackets >>> 32)); result = prime * result + ((user == null) ? 0 : user.hashCode()); result = prime * result + ((vnc == null) ? 0 : vnc.hashCode()); return result; @@ -281,7 +353,7 @@ public class Server extends Item { return false; if (getClass() != obj.getClass()) return false; - Server other = (Server) obj; + ServerInfo other = (ServerInfo) obj; if (bootDeviceIds == null) { if (other.bootDeviceIds != null) return false; @@ -308,11 +380,26 @@ public class Server extends Item { return false; if (persistent != other.persistent) return false; + if (rx != other.rx) + return false; + if (rxPackets != other.rxPackets) + return false; if (smp == null) { if (other.smp != null) return false; } else if (!smp.equals(other.smp)) return false; + if (started == null) { + if (other.started != null) + return false; + } else if (!started.equals(other.started)) + return false; + if (status != other.status) + return false; + if (tx != other.tx) + return false; + if (txPackets != other.txPackets) + return false; if (user == null) { if (other.user != null) return false; @@ -328,10 +415,11 @@ public class Server extends Item { @Override public String toString() { - return "[uuid=" + uuid + ", name=" + name + ", tags=" + tags + ", userMetadata=" + userMetadata + ", cpu=" + cpu - + ", smp=" + smp + ", mem=" + mem + ", persistent=" + persistent + ", devices=" + devices - + ", bootDeviceIds=" + bootDeviceIds + ", user=" + user + ", nics=" + nics + ", vnc=" + vnc - + ", description=" + description + "]"; + return "[uuid=" + uuid + ", name=" + name + ", tags=" + tags + ", userMetadata=" + userMetadata + + ", cpu=" + cpu + ", smp=" + smp + ", mem=" + mem + ", status=" + status + ", persistent=" + persistent + + ", started=" + started + ", devices=" + devices + ", bootDeviceIds=" + bootDeviceIds + ", user=" + user + + ", nics=" + nics + ", vnc=" + vnc + ", description=" + description + ", txPackets=" + txPackets + ", tx=" + + tx + ", rxPackets=" + rxPackets + ", rx=" + rx + "]"; } } \ No newline at end of file diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/ServerStatus.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/ServerStatus.java new file mode 100644 index 0000000000..2a53c67fd4 --- /dev/null +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/domain/ServerStatus.java @@ -0,0 +1,47 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.elasticstack.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * + * @author Adrian Cole + */ +public enum ServerStatus { + ACTIVE, STOPPED, PAUSED, DUMPED, DEAD, UNRECOGNIZED; + public String value() { + return name().toLowerCase(); + } + + @Override + public String toString() { + return value(); + } + + public static ServerStatus fromValue(String status) { + try { + return valueOf(checkNotNull(status, "status").toUpperCase()); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + +} \ No newline at end of file diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/KeyValuesDelimitedByBlankLinesToServerInfo.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/KeyValuesDelimitedByBlankLinesToServerInfo.java new file mode 100644 index 0000000000..027f79ff2b --- /dev/null +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/KeyValuesDelimitedByBlankLinesToServerInfo.java @@ -0,0 +1,53 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.elasticstack.functions; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.elasticstack.domain.ServerInfo; +import org.jclouds.http.HttpResponse; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class KeyValuesDelimitedByBlankLinesToServerInfo implements Function { + private final ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet setParser; + + @Inject + public KeyValuesDelimitedByBlankLinesToServerInfo(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet setParser) { + this.setParser = setParser; + } + + @Override + public ServerInfo apply(HttpResponse response) { + Set drives = setParser.apply(response); + if (drives.size() == 0) + return null; + return Iterables.get(drives, 0); + } +} \ No newline at end of file diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.java new file mode 100644 index 0000000000..5047b43085 --- /dev/null +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.java @@ -0,0 +1,60 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.elasticstack.functions; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.elasticstack.domain.ServerInfo; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ReturnStringIf2xx; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet implements Function> { + private final ReturnStringIf2xx returnStringIf200; + private final ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter; + private final MapToServerInfo mapToServer; + + @Inject + ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet(ReturnStringIf2xx returnStringIf200, + ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter, MapToServerInfo mapToServer) { + this.returnStringIf200 = returnStringIf200; + this.mapConverter = mapConverter; + this.mapToServer = mapToServer; + } + + @Override + public Set apply(HttpResponse response) { + String text = returnStringIf200.apply(response); + if (text == null || text.trim().equals("")) + return ImmutableSet. of(); + return ImmutableSet.copyOf(Iterables.transform(mapConverter.apply(text), mapToServer)); + } +} \ No newline at end of file diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/MapToDevices.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/MapToDevices.java new file mode 100644 index 0000000000..f7c9e64bcd --- /dev/null +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/MapToDevices.java @@ -0,0 +1,95 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.elasticstack.functions; + +import java.util.Map; +import java.util.Set; + +import javax.inject.Singleton; + +import org.jclouds.elasticstack.domain.BlockDevice; +import org.jclouds.elasticstack.domain.Device; +import org.jclouds.elasticstack.domain.IDEDevice; +import org.jclouds.elasticstack.domain.MediaType; +import org.jclouds.elasticstack.domain.SCSIDevice; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class MapToDevices implements Function, Set> { + + public Set apply(Map from) { + Builder devices = ImmutableSet.builder(); + addIDEDevices(from, devices); + addSCSIDevices(from, devices); + addBlockDevices(from, devices); + Set devicess = devices.build(); + return devicess; + } + + protected void addBlockDevices(Map from, Builder devices) { + BLOCK: for (int index : new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }) { + String key = String.format("block:0:%d", index); + if (!from.containsKey(key)) + break BLOCK; + devices.add(populateBuilder(new BlockDevice.Builder(index), key, from).build()); + } + } + + protected void addSCSIDevices(Map from, Builder devices) { + SCSI: for (int unit : new int[] { 0, 1, 2, 3, 4, 5, 6, 7 }) { + String key = String.format("scsi:0:%d", unit); + if (!from.containsKey(key)) + break SCSI; + devices.add(populateBuilder(new SCSIDevice.Builder(unit), key, from).build()); + } + } + + protected void addIDEDevices(Map from, Builder devices) { + IDE: for (int bus : new int[] { 0, 1 }) + for (int unit : new int[] { 0, 1 }) { + String key = String.format("ide:%d:%d", bus, unit); + if (!from.containsKey(key)) + break IDE; + devices.add(populateBuilder(new IDEDevice.Builder(bus, unit), key, from).build()); + } + } + + protected Device.Builder populateBuilder(Device.Builder deviceBuilder, String key, Map from) { + deviceBuilder.uuid(from.get(key)); + if (from.containsKey(key + ":read:bytes")) + deviceBuilder.readBytes(new Long(from.get(key + ":read:bytes"))); + if (from.containsKey(key + ":read:requests")) + deviceBuilder.readRequests(new Long(from.get(key + ":read:requests"))); + if (from.containsKey(key + ":write:bytes")) + deviceBuilder.writeBytes(new Long(from.get(key + ":write:bytes"))); + if (from.containsKey(key + ":write:requests")) + deviceBuilder.writeRequests(new Long(from.get(key + ":write:requests"))); + if (from.containsKey(key + ":media")) + deviceBuilder.mediaType(MediaType.fromValue(from.get(key + ":media"))); + return deviceBuilder; + } +} \ No newline at end of file diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/MapToNICs.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/MapToNICs.java new file mode 100644 index 0000000000..4303da4d10 --- /dev/null +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/MapToNICs.java @@ -0,0 +1,59 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.elasticstack.functions; + +import java.util.List; +import java.util.Map; + +import javax.inject.Singleton; + +import org.jclouds.elasticstack.domain.Model; +import org.jclouds.elasticstack.domain.NIC; + +import com.google.common.base.Function; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableList; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class MapToNICs implements Function, List> { + + @Override + public List apply(Map from) { + ImmutableList.Builder nics = ImmutableList.builder(); + NIC: for (int id : new int[] { 0, 1 }) { + String key = String.format("nic:%d", id); + if (!from.containsKey(key + ":model")) + break NIC; + NIC.Builder nicBuilder = new NIC.Builder(); + nicBuilder.dhcp(from.get(key + ":dhcp")); + nicBuilder.model(Model.fromValue(from.get(key + ":model"))); + nicBuilder.vlan(from.get(key + ":vlan")); + nicBuilder.mac(from.get(key + ":mac")); + if (from.containsKey(key + ":block")) + nicBuilder.block(Splitter.on(' ').split(from.get(key + ":block"))); + nics.add(nicBuilder.build()); + } + return nics.build(); + } +} \ No newline at end of file diff --git a/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/MapToServerInfo.java b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/MapToServerInfo.java new file mode 100644 index 0000000000..20221c82de --- /dev/null +++ b/sandbox/elasticstack/src/main/java/org/jclouds/elasticstack/functions/MapToServerInfo.java @@ -0,0 +1,101 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.elasticstack.functions; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.elasticstack.domain.Device; +import org.jclouds.elasticstack.domain.NIC; +import org.jclouds.elasticstack.domain.ServerInfo; +import org.jclouds.elasticstack.domain.ServerStatus; +import org.jclouds.elasticstack.domain.VNC; + +import com.google.common.base.Function; +import com.google.common.base.Splitter; +import com.google.common.collect.Maps; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class MapToServerInfo implements Function, ServerInfo> { + private final Function, Set> mapToDevices; + private final Function, List> mapToNICs; + + @Inject + public MapToServerInfo(Function, Set> mapToDevices, + Function, List> mapToNICs) { + this.mapToDevices = mapToDevices; + this.mapToNICs = mapToNICs; + } + + @Override + public ServerInfo apply(Map from) { + if (from.size() == 0) + return null; + ServerInfo.Builder builder = new ServerInfo.Builder(); + builder.name(from.get("name")); + builder.description(from.get("description")); + builder.persistent(Boolean.parseBoolean(from.get("persistent"))); + if (from.containsKey("tags")) + builder.tags(Splitter.on(' ').split(from.get("tags"))); + if (from.containsKey("status")) + builder.status(ServerStatus.fromValue(from.get("status"))); + if (from.containsKey("tx:packets")) + builder.txPackets(new Long(from.get("tx:packets"))); + if (from.containsKey("tx")) + builder.tx(new Long(from.get("tx"))); + if (from.containsKey("smp") && !"auto".equals(from.get("smp"))) + builder.smp(new Integer(from.get("smp"))); + builder.cpu(Integer.parseInt(from.get("cpu"))); + builder.mem(Integer.parseInt(from.get("mem"))); + builder.user(from.get("user")); + if (from.containsKey("started")) + builder.started(new Date(new Long(from.get("started")))); + builder.uuid(from.get("server")); + builder.vnc(new VNC(from.get("vnc:ip"), from.get("vnc:password"), from.containsKey("vnc:tls") + && Boolean.valueOf(from.get("vnc:tls")))); + if (from.containsKey("rx:packets")) + builder.rxPackets(new Long(from.get("rx:packets"))); + if (from.containsKey("rx")) + builder.rx(new Long(from.get("rx"))); + if (from.containsKey("boot")) + builder.bootDeviceIds(Splitter.on(' ').split(from.get("boot"))); + + Map metadata = Maps.newLinkedHashMap(); + for (Entry entry : from.entrySet()) { + if (entry.getKey().startsWith("user:")) + metadata.put(entry.getKey().substring(entry.getKey().indexOf(':') + 1), entry.getValue()); + } + builder.userMetadata(metadata); + + builder.nics(mapToNICs.apply(from)); + builder.devices(mapToDevices.apply(from)); + return builder.build(); + } +} \ No newline at end of file diff --git a/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/CommonElasticStackClientLiveTest.java b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/CommonElasticStackClientLiveTest.java index 28c8240a66..cf2afcc2e7 100644 --- a/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/CommonElasticStackClientLiveTest.java +++ b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/CommonElasticStackClientLiveTest.java @@ -32,6 +32,7 @@ import org.jclouds.elasticstack.domain.CreateDriveRequest; import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveInfo; import org.jclouds.elasticstack.domain.DriveStatus; +import org.jclouds.elasticstack.domain.ServerInfo; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContextFactory; @@ -97,6 +98,26 @@ public abstract class CommonElasticStackClientLiveTest servers = client.listServers(); + assertNotNull(servers); + } + + @Test + public void testListServerInfo() throws Exception { + Set servers = client.listServerInfo(); + assertNotNull(servers); + } + + @Test + public void testGetServer() throws Exception { + for (String serverUUID : client.listServers()) { + assert !"".equals(serverUUID); + assertNotNull(client.getServerInfo(serverUUID)); + } + } + @Test public void testListDrives() throws Exception { Set drives = client.listDrives(); diff --git a/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackAsyncClientTest.java b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackAsyncClientTest.java index 0cd9ebf7bf..b3ab118918 100644 --- a/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackAsyncClientTest.java +++ b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/ElasticStackAsyncClientTest.java @@ -31,7 +31,9 @@ import org.jclouds.elasticstack.domain.CreateDriveRequest; import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.ImageConversionType; import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; +import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToServerInfo; import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet; +import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet; import org.jclouds.elasticstack.functions.ReturnPayload; import org.jclouds.elasticstack.functions.SplitNewlines; import org.jclouds.elasticstack.options.ReadDriveOptions; @@ -60,6 +62,63 @@ import com.google.inject.TypeLiteral; */ @Test(groups = "unit", testName = "elasticstack.ElasticStackAsyncClientTest") public class ElasticStackAsyncClientTest extends RestClientTest { + public void testListServers() throws SecurityException, NoSuchMethodException, IOException { + Method method = ElasticStackAsyncClient.class.getMethod("listServers"); + GeneratedHttpRequest httpRequest = processor.createRequest(method); + + assertRequestLineEquals(httpRequest, "GET https://api.elasticstack.com/servers/list HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n"); + assertPayloadEquals(httpRequest, null, null, false); + + // now make sure request filters apply by replaying + Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + + assertRequestLineEquals(httpRequest, "GET https://api.elasticstack.com/servers/list HTTP/1.1"); + // for example, using basic authentication, we should get "only one" + // header + assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\nAuthorization: Basic Zm9vOmJhcg==\n"); + assertPayloadEquals(httpRequest, null, null, false); + + // TODO: insert expected response class, which probably extends ParseJson + assertResponseParserClassEquals(method, httpRequest, SplitNewlines.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpRequest); + + } + + public void testListServerInfo() throws SecurityException, NoSuchMethodException, IOException { + Method method = ElasticStackAsyncClient.class.getMethod("listServerInfo"); + GeneratedHttpRequest httpRequest = processor.createRequest(method); + + assertRequestLineEquals(httpRequest, "GET https://api.elasticstack.com/servers/info HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpRequest); + } + + public void testGetServerInfo() throws SecurityException, NoSuchMethodException, IOException { + Method method = ElasticStackAsyncClient.class.getMethod("getServerInfo", String.class); + GeneratedHttpRequest httpRequest = processor.createRequest(method, "uuid"); + + assertRequestLineEquals(httpRequest, "GET https://api.elasticstack.com/servers/uuid/info HTTP/1.1"); + assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\n"); + assertPayloadEquals(httpRequest, null, null, false); + + assertResponseParserClassEquals(method, httpRequest, KeyValuesDelimitedByBlankLinesToServerInfo.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(httpRequest); + + } public void testListDrives() throws SecurityException, NoSuchMethodException, IOException { Method method = ElasticStackAsyncClient.class.getMethod("listDrives"); @@ -76,8 +135,7 @@ public class ElasticStackAsyncClientTest extends RestClientTest + * + * ==================================================================== + * 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.elasticstack.functions; + +import static org.testng.Assert.assertEquals; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.jclouds.elasticstack.domain.Device; +import org.jclouds.elasticstack.domain.NIC; +import org.jclouds.http.HttpResponse; +import org.jclouds.io.Payloads; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.TypeLiteral; + +/** + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }) +public class KeyValuesDelimitedByBlankLinesToServerInfoTest { + + private static final KeyValuesDelimitedByBlankLinesToServerInfo FN = Guice.createInjector(new AbstractModule() { + + @Override + protected void configure() { + bind(new TypeLiteral, List>>() { + }).to(MapToNICs.class); + bind(new TypeLiteral, Set>>() { + }).to(MapToDevices.class); + } + + }).getInstance(KeyValuesDelimitedByBlankLinesToServerInfo.class); + + public void testNone() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload(""))), null); + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload("\n\n"))), null); + assertEquals(FN.apply(new HttpResponse(200, "", null)), null); + } + + public void testOne() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToServerInfoTest.class + .getResourceAsStream("/servers.txt")))), MapToServerInfoTest.ONE); + } +} \ No newline at end of file diff --git a/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSetTest.java b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSetTest.java new file mode 100644 index 0000000000..3741230731 --- /dev/null +++ b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/functions/ListOfKeyValuesDelimitedByBlankLinesToServerInfoSetTest.java @@ -0,0 +1,73 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.elasticstack.functions; + +import static org.testng.Assert.assertEquals; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.jclouds.elasticstack.domain.Device; +import org.jclouds.elasticstack.domain.NIC; +import org.jclouds.elasticstack.domain.ServerInfo; +import org.jclouds.http.HttpResponse; +import org.jclouds.io.Payloads; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.TypeLiteral; + +/** + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }) +public class ListOfKeyValuesDelimitedByBlankLinesToServerInfoSetTest { + + private static final ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet FN = Guice.createInjector( + new AbstractModule() { + + @Override + protected void configure() { + bind(new TypeLiteral, List>>() { + }).to(MapToNICs.class); + bind(new TypeLiteral, Set>>() { + }).to(MapToDevices.class); + } + + }).getInstance(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class); + + public void testNone() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload(""))), ImmutableSet. of()); + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload("\n\n"))), + ImmutableSet. of()); + assertEquals(FN.apply(new HttpResponse(200, "", null)), ImmutableSet. of()); + } + + public void testOne() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToServerInfoTest.class + .getResourceAsStream("/servers.txt")))), ImmutableSet. of(MapToServerInfoTest.ONE, + MapToServerInfoTest.TWO)); + } +} \ No newline at end of file diff --git a/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/functions/MapToServerInfoTest.java b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/functions/MapToServerInfoTest.java new file mode 100644 index 0000000000..6e446c5cd4 --- /dev/null +++ b/sandbox/elasticstack/src/test/java/org/jclouds/elasticstack/functions/MapToServerInfoTest.java @@ -0,0 +1,110 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.elasticstack.functions; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.util.Date; +import java.util.Map; + +import org.jclouds.elasticstack.domain.IDEDevice; +import org.jclouds.elasticstack.domain.MediaType; +import org.jclouds.elasticstack.domain.Model; +import org.jclouds.elasticstack.domain.NIC; +import org.jclouds.elasticstack.domain.ServerInfo; +import org.jclouds.elasticstack.domain.ServerStatus; +import org.jclouds.elasticstack.domain.VNC; +import org.jclouds.util.Utils; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }) +public class MapToServerInfoTest { + public static ServerInfo ONE = new ServerInfo.Builder() + .persistent(true) + .uuid("f8bee9cd-8e4b-4a05-8593-1314e3bfe49b") + .cpu(2000) + .bootDeviceIds(ImmutableSet.of("ide:0:0")) + .smp(1) + .mem(1024) + .status(ServerStatus.ACTIVE) + .started(new Date(1291493868l)) + .user("2f6244eb-50bc-4403-847e-f03cc3706a1f") + .name("jo") + .vnc(new VNC("46.20.114.124", "HfHzVmLT", false)) + .nics(ImmutableSet.of(new NIC.Builder() + .model(Model.E1000) + .dhcp("46.20.114.124") + .block( + ImmutableList.of("tcp/43594", "tcp/5902", "udp/5060", "tcp/5900", "tcp/5901", "tcp/21", "tcp/22", + "tcp/23", "tcp/25", "tcp/110", "tcp/143", "tcp/43595")).build())) + .devices( + ImmutableSet.of(new IDEDevice.Builder((int) 0, (int) 0).uuid("4af85ed3-0caa-4736-8a26-a33d7de0a122") + .readRequests(11154).readBytes(45686784).writeRequests(3698).writeBytes(15147008).build() + + )).tx(2550).txPackets(31).rx(455530).rxPackets(7583).build(); + + public static ServerInfo TWO = new ServerInfo.Builder() + .status(ServerStatus.STOPPED) + .name("Demo") + .mem(1024) + .cpu(2000) + .persistent(true) + .uuid("0f962616-2071-4173-be79-7dd084271edf") + .bootDeviceIds(ImmutableSet.of("ide:0:0")) + .user("2f6244eb-50bc-4403-847e-f03cc3706a1f") + .vnc(new VNC("auto", "HWbjvrg2", false)) + .nics(ImmutableSet.of(new NIC.Builder().model(Model.E1000).dhcp("auto").build())) + .devices( + ImmutableSet.of(new IDEDevice.Builder((int) 0, (int) 0).uuid("853bb98a-4fff-4c2f-a265-97c363f19ea5") + .mediaType(MediaType.CDROM).build() + + )).build(); + + private static final MapToServerInfo MAP_TO_DRIVE = new MapToServerInfo(new MapToDevices(), new MapToNICs()); + + public void testEmptyMapReturnsNull() { + assertEquals(MAP_TO_DRIVE.apply(ImmutableMap. of()), null); + } + + public void testBasics() { + ServerInfo expects = new ServerInfo.Builder().name("foo").uuid("hello").vnc(new VNC("auto", null, false)) + .cpu(1000).mem(2048).build(); + assertEquals(MAP_TO_DRIVE.apply(ImmutableMap.of("name", "foo", "server", "hello", "vnc:ip", "auto", "cpu", + "1000", "mem", "2048")), expects); + } + + public void testComplete() throws IOException { + + Map input = new ListOfKeyValuesDelimitedByBlankLinesToListOfMaps().apply( + Utils.toStringAndClose(MapToServerInfoTest.class.getResourceAsStream("/servers.txt"))).get(0); + + assertEquals(MAP_TO_DRIVE.apply(input), ONE); + + } +} \ No newline at end of file diff --git a/sandbox/elasticstack/src/test/resources/servers.txt b/sandbox/elasticstack/src/test/resources/servers.txt new file mode 100644 index 0000000000..a3d1ff1b46 --- /dev/null +++ b/sandbox/elasticstack/src/test/resources/servers.txt @@ -0,0 +1,40 @@ +ide:0:0:write:requests 3698 +boot ide:0:0 +vnc:password HfHzVmLT +ide:0:0 4af85ed3-0caa-4736-8a26-a33d7de0a122 +ide:0:0:read:requests 11154 +ide:0:0:read:bytes 45686784 +vnc:ip 46.20.114.124 +tx:packets 31 +tx 2550 +rx 455530 +smp 1 +mem 1024 +nic:0:model e1000 +status active +started 1291493868 +rx:packets 7583 +user 2f6244eb-50bc-4403-847e-f03cc3706a1f +name jo +persistent true +nic:0:block tcp/43594 tcp/5902 udp/5060 tcp/5900 tcp/5901 tcp/21 tcp/22 tcp/23 tcp/25 tcp/110 tcp/143 tcp/43595 +server f8bee9cd-8e4b-4a05-8593-1314e3bfe49b +nic:0:dhcp 46.20.114.124 +ide:0:0:write:bytes 15147008 +cpu 2000 + +status stopped +name Demo +mem 1024 +boot ide:0:0 +vnc:password HWbjvrg2 +persistent true +server 0f962616-2071-4173-be79-7dd084271edf +smp auto +nic:0:dhcp auto +user 2f6244eb-50bc-4403-847e-f03cc3706a1f +nic:0:model e1000 +vnc:ip auto +ide:0:0 853bb98a-4fff-4c2f-a265-97c363f19ea5 +cpu 2000 +ide:0:0:media cdrom