Issue 412: added elasticstack read-only commands for servers

This commit is contained in:
Adrian Cole 2010-12-04 23:26:16 +00:00
parent 92a9e2f562
commit 6e975662c1
23 changed files with 1328 additions and 53 deletions

140
sandbox/cloudsigma/pom.xml Normal file
View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2010 Cloud Conscious, LLC <info@cloudconscious.com>
====================================================================
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF 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.html
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.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-cloudsigma</artifactId>
<name>jclouds cloudsigma core</name>
<description>jclouds components to access cloudsigma</description>
<!-- bootstrapping: need to fetch the project POM -->
<repositories>
<repository>
<id>jclouds-googlecode-deploy</id>
<url>http://jclouds.googlecode.com/svn/repo</url>
</repository>
<repository>
<id>jclouds-rimu-snapshots-nexus</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<!-- when instances are hung, open a ticket and add here -->
<jclouds.compute.blacklist-nodes>trmkrun-ccc,test.trmk-924</jclouds.compute.blacklist-nodes>
<test.cloudsigma.endpoint>https://api.cloudsigma.com</test.cloudsigma.endpoint>
<test.cloudsigma.apiversion>1.0</test.cloudsigma.apiversion>
<test.cloudsigma.identity>FIXME</test.cloudsigma.identity>
<test.cloudsigma.credential>FIXME</test.cloudsigma.credential>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-elasticstack</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-elasticstack</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemProperties>
<property>
<name>test.cloudsigma.endpoint</name>
<value>${test.cloudsigma.endpoint}</value>
</property>
<property>
<name>test.cloudsigma.apiversion</name>
<value>${test.cloudsigma.apiversion}</value>
</property>
<property>
<name>test.cloudsigma.identity</name>
<value>${test.cloudsigma.identity}</value>
</property>
<property>
<name>test.cloudsigma.credential</name>
<value>${test.cloudsigma.credential}</value>
</property>
<property>
<name>jclouds.compute.blacklist-nodes</name>
<value>${jclouds.compute.blacklist-nodes}</value>
</property>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -19,14 +19,20 @@
package org.jclouds.cloudsigma.config; package org.jclouds.cloudsigma.config;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.jclouds.cloudsigma.CloudSigmaAsyncClient; import org.jclouds.cloudsigma.CloudSigmaAsyncClient;
import org.jclouds.cloudsigma.CloudSigmaClient; import org.jclouds.cloudsigma.CloudSigmaClient;
import org.jclouds.cloudsigma.functions.CreateDriveRequestToMap; import org.jclouds.cloudsigma.functions.CreateDriveRequestToMap;
import org.jclouds.cloudsigma.functions.DriveDataToMap; import org.jclouds.cloudsigma.functions.DriveDataToMap;
import org.jclouds.elasticstack.domain.CreateDriveRequest; import org.jclouds.elasticstack.domain.CreateDriveRequest;
import org.jclouds.elasticstack.domain.Device;
import org.jclouds.elasticstack.domain.DriveData; 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.elasticstack.handlers.ElasticStackErrorHandler;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
@ -66,6 +72,10 @@ public class CloudSigmaRestClientModule extends RestClientModule<CloudSigmaClien
}).to(CreateDriveRequestToMap.class); }).to(CreateDriveRequestToMap.class);
bind(new TypeLiteral<Function<DriveData, Map<String, String>>>() { bind(new TypeLiteral<Function<DriveData, Map<String, String>>>() {
}).to(DriveDataToMap.class); }).to(DriveDataToMap.class);
bind(new TypeLiteral<Function<Map<String, String>, List<NIC>>>() {
}).to(MapToNICs.class);
bind(new TypeLiteral<Function<Map<String, String>, Set<Device>>>() {
}).to(MapToDevices.class);
} }
@Override @Override

View File

@ -33,8 +33,11 @@ import org.jclouds.elasticstack.binders.BindDriveDataToPlainTextString;
import org.jclouds.elasticstack.domain.CreateDriveRequest; import org.jclouds.elasticstack.domain.CreateDriveRequest;
import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveData;
import org.jclouds.elasticstack.domain.DriveInfo; import org.jclouds.elasticstack.domain.DriveInfo;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToServerInfo;
import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet; import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet;
import org.jclouds.elasticstack.functions.SplitNewlines; import org.jclouds.elasticstack.functions.SplitNewlines;
import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
@ -58,6 +61,31 @@ import com.google.common.util.concurrent.ListenableFuture;
@Consumes(MediaType.TEXT_PLAIN) @Consumes(MediaType.TEXT_PLAIN)
public interface CommonElasticStackAsyncClient { public interface CommonElasticStackAsyncClient {
/**
* @see ElasticStackClient#listServers()
*/
@GET
@Path("/servers/list")
@ResponseParser(SplitNewlines.class)
ListenableFuture<Set<String>> listServers();
/**
* @see ElasticStackClient#listServerInfo()
*/
@GET
@Path("/servers/info")
@ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class)
ListenableFuture<Set<? extends ServerInfo>> listServerInfo();
/**
* @see ElasticStackClient#getServerInfo
*/
@GET
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
@ResponseParser(KeyValuesDelimitedByBlankLinesToServerInfo.class)
@Path("/servers/{uuid}/info")
ListenableFuture<? extends ServerInfo> getServerInfo(@PathParam("uuid") String uuid);
/** /**
* @see ElasticStackClient#listDrives() * @see ElasticStackClient#listDrives()
*/ */

View File

@ -26,6 +26,7 @@ import org.jclouds.concurrent.Timeout;
import org.jclouds.elasticstack.domain.CreateDriveRequest; import org.jclouds.elasticstack.domain.CreateDriveRequest;
import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveData;
import org.jclouds.elasticstack.domain.DriveInfo; import org.jclouds.elasticstack.domain.DriveInfo;
import org.jclouds.elasticstack.domain.ServerInfo;
/** /**
* Provides synchronous access to elasticstack. * Provides synchronous access to elasticstack.
@ -37,6 +38,27 @@ import org.jclouds.elasticstack.domain.DriveInfo;
*/ */
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface CommonElasticStackClient { public interface CommonElasticStackClient {
/**
* list of server uuids in your account
*
* @return or empty set if no servers are found
*/
Set<String> listServers();
/**
* Get all servers info
*
* @return or empty set if no servers are found
*/
Set<? extends ServerInfo> listServerInfo();
/**
* @param uuid
* what to get
* @return null, if not found
*/
ServerInfo getServerInfo(String uuid);
/** /**
* list of drive uuids in your account * list of drive uuids in your account
* *
@ -86,5 +108,4 @@ public interface CommonElasticStackClient {
*/ */
void destroyDrive(String uuid); void destroyDrive(String uuid);
} }

View File

@ -19,14 +19,20 @@
package org.jclouds.elasticstack.config; package org.jclouds.elasticstack.config;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.jclouds.elasticstack.ElasticStackAsyncClient; import org.jclouds.elasticstack.ElasticStackAsyncClient;
import org.jclouds.elasticstack.ElasticStackClient; import org.jclouds.elasticstack.ElasticStackClient;
import org.jclouds.elasticstack.domain.CreateDriveRequest; import org.jclouds.elasticstack.domain.CreateDriveRequest;
import org.jclouds.elasticstack.domain.Device;
import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveData;
import org.jclouds.elasticstack.domain.NIC;
import org.jclouds.elasticstack.functions.CreateDriveRequestToMap; import org.jclouds.elasticstack.functions.CreateDriveRequestToMap;
import org.jclouds.elasticstack.functions.DriveDataToMap; 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.elasticstack.handlers.ElasticStackErrorHandler;
import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.RequiresHttp; import org.jclouds.http.RequiresHttp;
@ -59,6 +65,10 @@ public class ElasticStackRestClientModule extends RestClientModule<ElasticStackC
}).to(CreateDriveRequestToMap.class); }).to(CreateDriveRequestToMap.class);
bind(new TypeLiteral<Function<DriveData, Map<String, String>>>() { bind(new TypeLiteral<Function<DriveData, Map<String, String>>>() {
}).to(DriveDataToMap.class); }).to(DriveDataToMap.class);
bind(new TypeLiteral<Function<Map<String, String>, List<NIC>>>() {
}).to(MapToNICs.class);
bind(new TypeLiteral<Function<Map<String, String>, Set<Device>>>() {
}).to(MapToDevices.class);
} }
@Override @Override

View File

@ -26,11 +26,25 @@ import static com.google.common.base.Preconditions.checkArgument;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class BlockDevice extends Device { 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) { @Override
super(driveUuid, mediaType); 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"); checkArgument(index >= 0 && index < 8, "index must be between 0 and 7");
this.index = index; this.index = index;
} }
@ -62,7 +76,7 @@ public class BlockDevice extends Device {
return String.format("block:%d", index); return String.format("block:%d", index);
} }
public char getIndex() { public int getIndex() {
return index; return index;
} }

View File

@ -26,12 +26,62 @@ import static com.google.common.base.Preconditions.checkNotNull;
* @author Adrian Cole * @author Adrian Cole
*/ */
public abstract class Device { 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 String driveUuid;
protected final MediaType mediaType; 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.driveUuid = checkNotNull(driveUuid, "driveUuid");
this.mediaType = checkNotNull(mediaType, "mediaType"); 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 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 @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((driveUuid == null) ? 0 : driveUuid.hashCode()); result = prime * result + ((driveUuid == null) ? 0 : driveUuid.hashCode());
result = prime * result + ((mediaType == null) ? 0 : mediaType.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; return result;
} }
@ -81,11 +167,20 @@ public abstract class Device {
return false; return false;
if (mediaType != other.mediaType) if (mediaType != other.mediaType)
return false; 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; return true;
} }
@Override @Override
public String toString() { public String toString() {
return "[driveUuid=" + driveUuid + ", mediaType=" + mediaType + "]"; return "[driveUuid=" + driveUuid + ", mediaType=" + mediaType + ", readBytes=" + readBytes + ", readRequests="
+ readRequests + ", writeBytes=" + writeBytes + ", writeRequests=" + writeRequests + "]";
} }
} }

View File

@ -26,12 +26,28 @@ import static com.google.common.base.Preconditions.checkArgument;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class IDEDevice extends Device { public class IDEDevice extends Device {
public static class Builder extends Device.Builder {
private final int bus;
private final int unit;
private final char bus; public Builder(int bus, int unit) {
private final char unit; this.bus = bus;
this.unit = unit;
}
public IDEDevice(String driveUuid, MediaType mediaType, char bus, char unit) { @Override
super(driveUuid, mediaType); 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(bus == 0 || bus == 1, "bus must be 0 or 1");
checkArgument(unit == 0 || unit == 1, "unit must be 0 or 1"); checkArgument(unit == 0 || unit == 1, "unit must be 0 or 1");
this.bus = bus; this.bus = bus;
@ -68,11 +84,11 @@ public class IDEDevice extends Device {
return String.format("ide:%d:%d", bus, unit); return String.format("ide:%d:%d", bus, unit);
} }
public char getBus() { public int getBus() {
return bus; return bus;
} }
public char getUnit() { public int getUnit() {
return unit; return unit;
} }

View File

@ -21,23 +21,66 @@ package org.jclouds.elasticstack.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.google.common.collect.ImmutableSet;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class NIC { public class NIC {
public static class Builder {
private String dhcp;
private Model model;
private String vlan;
private String mac;
private Set<String> 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<String> 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 String dhcp;
private final Model model; private final Model model;
private final String vlan; private final String vlan;
private final String mac; private final String mac;
private final Set<String> 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<String> block) {
this.dhcp = dhcp; this.dhcp = dhcp;
this.model = checkNotNull(model, "model"); this.model = checkNotNull(model, "model");
this.vlan = vlan; this.vlan = vlan;
this.mac = mac; this.mac = mac;
this.block = ImmutableSet.copyOf(checkNotNull(block, "block"));
} }
/** /**
@ -75,10 +118,16 @@ public class NIC {
return mac; return mac;
} }
// TODO undocumented
public Set<String> getBlock() {
return block;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((block == null) ? 0 : block.hashCode());
result = prime * result + ((dhcp == null) ? 0 : dhcp.hashCode()); result = prime * result + ((dhcp == null) ? 0 : dhcp.hashCode());
result = prime * result + ((mac == null) ? 0 : mac.hashCode()); result = prime * result + ((mac == null) ? 0 : mac.hashCode());
result = prime * result + ((model == null) ? 0 : model.hashCode()); result = prime * result + ((model == null) ? 0 : model.hashCode());
@ -95,6 +144,11 @@ public class NIC {
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
NIC other = (NIC) obj; 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 (dhcp == null) {
if (other.dhcp != null) if (other.dhcp != null)
return false; return false;
@ -117,6 +171,6 @@ public class NIC {
@Override @Override
public String toString() { public String toString() {
return "[dhcp=" + dhcp + ", model=" + model + ", vlan=" + vlan + ", mac=" + mac + "]"; return "[dhcp=" + dhcp + ", model=" + model + ", vlan=" + vlan + ", mac=" + mac + ", block=" + block + "]";
} }
} }

View File

@ -26,12 +26,26 @@ import static com.google.common.base.Preconditions.checkArgument;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class SCSIDevice extends Device { public class SCSIDevice extends Device {
public static class Builder extends Device.Builder {
private final int unit;
private final char bus = 0; public Builder(int unit) {
private final char unit; this.unit = unit;
}
public SCSIDevice(String driveUuid, MediaType mediaType, char unit) { @Override
super(driveUuid, mediaType); 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"); checkArgument(unit >= 0 && unit < 8, "unit must be between 0 and 7");
this.unit = unit; this.unit = unit;
} }
@ -61,11 +75,11 @@ public class SCSIDevice extends Device {
return true; return true;
} }
public char getBus() { public int getBus() {
return bus; return bus;
} }
public char getUnit() { public int getUnit() {
return unit; return unit;
} }

View File

@ -21,6 +21,7 @@ package org.jclouds.elasticstack.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -34,31 +35,15 @@ import com.google.common.collect.ImmutableSet;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class Server extends Item { public class ServerInfo 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 static class Builder extends Item.Builder { public static class Builder extends Item.Builder {
protected int cpu; protected int cpu;
protected Integer smp; protected Integer smp;
protected ServerStatus status;
protected int mem; protected int mem;
protected boolean persistent; protected boolean persistent;
protected Date started;
protected Set<? extends Device> devices = ImmutableSet.of(); protected Set<? extends Device> devices = ImmutableSet.of();
protected Set<String> bootDeviceIds = ImmutableSet.of(); protected Set<String> bootDeviceIds = ImmutableSet.of();
protected List<NIC> nics = ImmutableList.of(); protected List<NIC> nics = ImmutableList.of();
@ -66,6 +51,15 @@ public class Server extends Item {
protected VNC vnc; protected VNC vnc;
// TODO undocumented // TODO undocumented
protected String description; 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) { public Builder cpu(int cpu) {
this.cpu = cpu; this.cpu = cpu;
@ -87,6 +81,11 @@ public class Server extends Item {
return this; return this;
} }
public Builder started(Date started) {
this.started = started;
return this;
}
public Builder devices(Iterable<? extends Device> devices) { public Builder devices(Iterable<? extends Device> devices) {
this.devices = ImmutableSet.copyOf(checkNotNull(devices, "devices")); this.devices = ImmutableSet.copyOf(checkNotNull(devices, "devices"));
return this; return this;
@ -117,6 +116,26 @@ public class Server extends Item {
return this; 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} * {@inheritDoc}
*/ */
@ -149,16 +168,19 @@ public class Server extends Item {
return Builder.class.cast(super.userMetadata(userMetadata)); return Builder.class.cast(super.userMetadata(userMetadata));
} }
public Server build() { public ServerInfo build() {
return new Server(uuid, name, cpu, smp, mem, persistent, devices, tags, bootDeviceIds, userMetadata, nics, return new ServerInfo(uuid, name, cpu, smp, mem, status, persistent, started, devices, tags, bootDeviceIds,
user, vnc, description); userMetadata, nics, user, vnc, description, tx, txPackets, rx, rxPackets);
} }
} }
protected final int cpu; protected final int cpu;
protected final Integer smp; protected final Integer smp;
protected final int mem; protected final int mem;
protected final ServerStatus status;
protected final boolean persistent; protected final boolean persistent;
@Nullable
protected final Date started;
protected final Set<? extends Device> devices; protected final Set<? extends Device> devices;
protected final Set<String> bootDeviceIds; protected final Set<String> bootDeviceIds;
@Nullable @Nullable
@ -167,21 +189,32 @@ public class Server extends Item {
protected final VNC vnc; protected final VNC vnc;
@Nullable @Nullable
private final String description; 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, public ServerInfo(@Nullable String uuid, String name, int cpu, @Nullable Integer smp, int mem, ServerStatus status,
Iterable<? extends Device> devices, Iterable<String> bootDeviceIds, Iterable<String> tags, boolean persistent, @Nullable Date started, Iterable<? extends Device> devices,
Map<String, String> userMetadata, Iterable<NIC> nics, @Nullable String user, VNC vnc, String description) { Iterable<String> bootDeviceIds, Iterable<String> tags, Map<String, String> userMetadata, Iterable<NIC> nics,
@Nullable String user, VNC vnc, String description, long tx, long txPackets, long rx, long rxPackets) {
super(uuid, name, tags, userMetadata); super(uuid, name, tags, userMetadata);
this.cpu = cpu; this.cpu = cpu;
this.smp = smp; this.smp = smp;
this.mem = mem; this.mem = mem;
this.status = status;
this.persistent = persistent; this.persistent = persistent;
this.started = started;
this.devices = ImmutableSet.copyOf(checkNotNull(devices, "devices")); this.devices = ImmutableSet.copyOf(checkNotNull(devices, "devices"));
this.bootDeviceIds = ImmutableSet.copyOf(checkNotNull(bootDeviceIds, "bootDeviceIds")); this.bootDeviceIds = ImmutableSet.copyOf(checkNotNull(bootDeviceIds, "bootDeviceIds"));
this.nics = ImmutableList.copyOf(checkNotNull(nics, "nics")); this.nics = ImmutableList.copyOf(checkNotNull(nics, "nics"));
this.user = user; this.user = user;
this.vnc = checkNotNull(vnc, "vnc"); this.vnc = checkNotNull(vnc, "vnc");
this.description = description; 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 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, * @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; 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 // TODO undocumented
/** /**
* *
@ -267,7 +333,13 @@ public class Server extends Item {
result = prime * result + mem; result = prime * result + mem;
result = prime * result + ((nics == null) ? 0 : nics.hashCode()); result = prime * result + ((nics == null) ? 0 : nics.hashCode());
result = prime * result + (persistent ? 1231 : 1237); 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 + ((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 + ((user == null) ? 0 : user.hashCode());
result = prime * result + ((vnc == null) ? 0 : vnc.hashCode()); result = prime * result + ((vnc == null) ? 0 : vnc.hashCode());
return result; return result;
@ -281,7 +353,7 @@ public class Server extends Item {
return false; return false;
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
Server other = (Server) obj; ServerInfo other = (ServerInfo) obj;
if (bootDeviceIds == null) { if (bootDeviceIds == null) {
if (other.bootDeviceIds != null) if (other.bootDeviceIds != null)
return false; return false;
@ -308,11 +380,26 @@ public class Server extends Item {
return false; return false;
if (persistent != other.persistent) if (persistent != other.persistent)
return false; return false;
if (rx != other.rx)
return false;
if (rxPackets != other.rxPackets)
return false;
if (smp == null) { if (smp == null) {
if (other.smp != null) if (other.smp != null)
return false; return false;
} else if (!smp.equals(other.smp)) } else if (!smp.equals(other.smp))
return false; 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 (user == null) {
if (other.user != null) if (other.user != null)
return false; return false;
@ -328,10 +415,11 @@ public class Server extends Item {
@Override @Override
public String toString() { public String toString() {
return "[uuid=" + uuid + ", name=" + name + ", tags=" + tags + ", userMetadata=" + userMetadata + ", cpu=" + cpu return "[uuid=" + uuid + ", name=" + name + ", tags=" + tags + ", userMetadata=" + userMetadata
+ ", smp=" + smp + ", mem=" + mem + ", persistent=" + persistent + ", devices=" + devices + ", cpu=" + cpu + ", smp=" + smp + ", mem=" + mem + ", status=" + status + ", persistent=" + persistent
+ ", bootDeviceIds=" + bootDeviceIds + ", user=" + user + ", nics=" + nics + ", vnc=" + vnc + ", started=" + started + ", devices=" + devices + ", bootDeviceIds=" + bootDeviceIds + ", user=" + user
+ ", description=" + description + "]"; + ", nics=" + nics + ", vnc=" + vnc + ", description=" + description + ", txPackets=" + txPackets + ", tx="
+ tx + ", rxPackets=" + rxPackets + ", rx=" + rx + "]";
} }
} }

View File

@ -0,0 +1,47 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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;
}
}
}

View File

@ -0,0 +1,53 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<HttpResponse, ServerInfo> {
private final ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet setParser;
@Inject
public KeyValuesDelimitedByBlankLinesToServerInfo(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet setParser) {
this.setParser = setParser;
}
@Override
public ServerInfo apply(HttpResponse response) {
Set<ServerInfo> drives = setParser.apply(response);
if (drives.size() == 0)
return null;
return Iterables.get(drives, 0);
}
}

View File

@ -0,0 +1,60 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<HttpResponse, Set<ServerInfo>> {
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<ServerInfo> apply(HttpResponse response) {
String text = returnStringIf200.apply(response);
if (text == null || text.trim().equals(""))
return ImmutableSet.<ServerInfo> of();
return ImmutableSet.copyOf(Iterables.transform(mapConverter.apply(text), mapToServer));
}
}

View File

@ -0,0 +1,95 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<Map<String, String>, Set<Device>> {
public Set<Device> apply(Map<String, String> from) {
Builder<Device> devices = ImmutableSet.builder();
addIDEDevices(from, devices);
addSCSIDevices(from, devices);
addBlockDevices(from, devices);
Set<Device> devicess = devices.build();
return devicess;
}
protected void addBlockDevices(Map<String, String> from, Builder<Device> 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<String, String> from, Builder<Device> 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<String, String> from, Builder<Device> 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<String, String> 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;
}
}

View File

@ -0,0 +1,59 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<Map<String, String>, List<NIC>> {
@Override
public List<NIC> apply(Map<String, String> from) {
ImmutableList.Builder<NIC> 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();
}
}

View File

@ -0,0 +1,101 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<Map<String, String>, ServerInfo> {
private final Function<Map<String, String>, Set<Device>> mapToDevices;
private final Function<Map<String, String>, List<NIC>> mapToNICs;
@Inject
public MapToServerInfo(Function<Map<String, String>, Set<Device>> mapToDevices,
Function<Map<String, String>, List<NIC>> mapToNICs) {
this.mapToDevices = mapToDevices;
this.mapToNICs = mapToNICs;
}
@Override
public ServerInfo apply(Map<String, String> 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<String, String> metadata = Maps.newLinkedHashMap();
for (Entry<String, String> 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();
}
}

View File

@ -32,6 +32,7 @@ import org.jclouds.elasticstack.domain.CreateDriveRequest;
import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveData;
import org.jclouds.elasticstack.domain.DriveInfo; import org.jclouds.elasticstack.domain.DriveInfo;
import org.jclouds.elasticstack.domain.DriveStatus; import org.jclouds.elasticstack.domain.DriveStatus;
import org.jclouds.elasticstack.domain.ServerInfo;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory; import org.jclouds.rest.RestContextFactory;
@ -97,6 +98,26 @@ public abstract class CommonElasticStackClientLiveTest<S extends CommonElasticSt
context.close(); context.close();
} }
@Test
public void testListServers() throws Exception {
Set<String> servers = client.listServers();
assertNotNull(servers);
}
@Test
public void testListServerInfo() throws Exception {
Set<? extends ServerInfo> servers = client.listServerInfo();
assertNotNull(servers);
}
@Test
public void testGetServer() throws Exception {
for (String serverUUID : client.listServers()) {
assert !"".equals(serverUUID);
assertNotNull(client.getServerInfo(serverUUID));
}
}
@Test @Test
public void testListDrives() throws Exception { public void testListDrives() throws Exception {
Set<String> drives = client.listDrives(); Set<String> drives = client.listDrives();

View File

@ -31,7 +31,9 @@ import org.jclouds.elasticstack.domain.CreateDriveRequest;
import org.jclouds.elasticstack.domain.DriveData; import org.jclouds.elasticstack.domain.DriveData;
import org.jclouds.elasticstack.domain.ImageConversionType; import org.jclouds.elasticstack.domain.ImageConversionType;
import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
import org.jclouds.elasticstack.functions.KeyValuesDelimitedByBlankLinesToServerInfo;
import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet; import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
import org.jclouds.elasticstack.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet;
import org.jclouds.elasticstack.functions.ReturnPayload; import org.jclouds.elasticstack.functions.ReturnPayload;
import org.jclouds.elasticstack.functions.SplitNewlines; import org.jclouds.elasticstack.functions.SplitNewlines;
import org.jclouds.elasticstack.options.ReadDriveOptions; import org.jclouds.elasticstack.options.ReadDriveOptions;
@ -60,6 +62,63 @@ import com.google.inject.TypeLiteral;
*/ */
@Test(groups = "unit", testName = "elasticstack.ElasticStackAsyncClientTest") @Test(groups = "unit", testName = "elasticstack.ElasticStackAsyncClientTest")
public class ElasticStackAsyncClientTest extends RestClientTest<ElasticStackAsyncClient> { public class ElasticStackAsyncClientTest extends RestClientTest<ElasticStackAsyncClient> {
public void testListServers() throws SecurityException, NoSuchMethodException, IOException {
Method method = ElasticStackAsyncClient.class.getMethod("listServers");
GeneratedHttpRequest<ElasticStackAsyncClient> 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<ElasticStackAsyncClient> 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<ElasticStackAsyncClient> 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 { public void testListDrives() throws SecurityException, NoSuchMethodException, IOException {
Method method = ElasticStackAsyncClient.class.getMethod("listDrives"); Method method = ElasticStackAsyncClient.class.getMethod("listDrives");
@ -76,8 +135,7 @@ public class ElasticStackAsyncClientTest extends RestClientTest<ElasticStackAsyn
assertRequestLineEquals(httpRequest, "GET https://api.elasticstack.com/drives/list HTTP/1.1"); assertRequestLineEquals(httpRequest, "GET https://api.elasticstack.com/drives/list HTTP/1.1");
// for example, using basic authentication, we should get "only one" // for example, using basic authentication, we should get "only one"
// header // header
assertNonPayloadHeadersEqual(httpRequest, assertNonPayloadHeadersEqual(httpRequest, "Accept: text/plain\nAuthorization: Basic Zm9vOmJhcg==\n");
"Accept: text/plain\nAuthorization: Basic Zm9vOmJhcg==\n");
assertPayloadEquals(httpRequest, null, null, false); assertPayloadEquals(httpRequest, null, null, false);
// TODO: insert expected response class, which probably extends ParseJson // TODO: insert expected response class, which probably extends ParseJson

View File

@ -0,0 +1,68 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<Function<Map<String, String>, List<NIC>>>() {
}).to(MapToNICs.class);
bind(new TypeLiteral<Function<Map<String, String>, Set<Device>>>() {
}).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);
}
}

View File

@ -0,0 +1,73 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<Function<Map<String, String>, List<NIC>>>() {
}).to(MapToNICs.class);
bind(new TypeLiteral<Function<Map<String, String>, Set<Device>>>() {
}).to(MapToDevices.class);
}
}).getInstance(ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet.class);
public void testNone() {
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload(""))), ImmutableSet.<ServerInfo> of());
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload("\n\n"))),
ImmutableSet.<ServerInfo> of());
assertEquals(FN.apply(new HttpResponse(200, "", null)), ImmutableSet.<ServerInfo> of());
}
public void testOne() {
assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToServerInfoTest.class
.getResourceAsStream("/servers.txt")))), ImmutableSet.<ServerInfo> of(MapToServerInfoTest.ONE,
MapToServerInfoTest.TWO));
}
}

View File

@ -0,0 +1,110 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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.<String, String> 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<String, String> input = new ListOfKeyValuesDelimitedByBlankLinesToListOfMaps().apply(
Utils.toStringAndClose(MapToServerInfoTest.class.getResourceAsStream("/servers.txt"))).get(0);
assertEquals(MAP_TO_DRIVE.apply(input), ONE);
}
}

View File

@ -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