Issue 518:add limits operation to CloudServersClient

This commit is contained in:
Adrian Cole 2011-04-08 12:51:53 -07:00
parent a3fc778035
commit ad96923db7
6 changed files with 179 additions and 48 deletions

View File

@ -37,6 +37,7 @@ import org.jclouds.cloudservers.domain.Addresses;
import org.jclouds.cloudservers.domain.BackupSchedule;
import org.jclouds.cloudservers.domain.Flavor;
import org.jclouds.cloudservers.domain.Image;
import org.jclouds.cloudservers.domain.Limits;
import org.jclouds.cloudservers.domain.RebootType;
import org.jclouds.cloudservers.domain.Server;
import org.jclouds.cloudservers.domain.SharedIpGroup;
@ -80,6 +81,17 @@ import com.google.common.util.concurrent.ListenableFuture;
@Endpoint(ServerManagement.class)
public interface CloudServersAsyncClient {
/**
* @see CloudServersClient#getLimits
*/
@GET
@Unwrap
@Consumes(MediaType.APPLICATION_JSON)
@QueryParams(keys = "format", values = "json")
@Path("/limits")
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Limits> getLimits();
/**
* @see CloudServersClient#listServers
*/

View File

@ -21,15 +21,16 @@ package org.jclouds.cloudservers;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.PathParam;
import org.jclouds.concurrent.Timeout;
import org.jclouds.cloudservers.domain.Addresses;
import org.jclouds.cloudservers.domain.BackupSchedule;
import org.jclouds.cloudservers.domain.Flavor;
import org.jclouds.cloudservers.domain.Image;
import org.jclouds.cloudservers.domain.Limits;
import org.jclouds.cloudservers.domain.RebootType;
import org.jclouds.cloudservers.domain.Server;
import org.jclouds.cloudservers.domain.SharedIpGroup;
@ -37,16 +38,14 @@ import org.jclouds.cloudservers.options.CreateServerOptions;
import org.jclouds.cloudservers.options.CreateSharedIpGroupOptions;
import org.jclouds.cloudservers.options.ListOptions;
import org.jclouds.cloudservers.options.RebuildServerOptions;
import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.ResourceNotFoundException;
import java.util.concurrent.Future;
/**
* Provides access to Cloud Servers via their REST API.
* <p/>
* All commands return a Future of the result from Cloud Servers. Any exceptions incurred
* during processing will be wrapped in an {@link ExecutionException} as documented in
* {@link Future#get()}.
* All commands return a Future of the result from Cloud Servers. Any exceptions incurred during
* processing will be wrapped in an {@link ExecutionException} as documented in {@link Future#get()}.
*
* @see CloudServersAsyncClient
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
@ -54,13 +53,22 @@ import java.util.concurrent.Future;
*/
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
public interface CloudServersClient {
/**
* All accounts, by default, have a preconfigured set of thresholds (or limits) to manage
* capacity and prevent abuse of the system. The system recognizes two kinds of limits: rate
* limits and absolute limits. Rate limits are thresholds that are reset after a certain amount
* of time passes. Absolute limits are fixed.
*
* @return limits on the account
*/
Limits getLimits();
/**
*
* List all servers (IDs and names only)
*
* This operation provides a list of servers associated with your identity. Servers that have been
* deleted are not included in this list.
* This operation provides a list of servers associated with your identity. Servers that have
* been deleted are not included in this list.
* <p/>
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
* withDetails()}
@ -194,8 +202,7 @@ public interface CloudServersClient {
* (e.g. keepalived) can then be used within the servers to perform health checks and
* manage IP failover.
*/
void shareIp(String addressToShare, int serverToTosignBindressTo, int sharedIpGroup,
boolean configureServer);
void shareIp(String addressToShare, int serverToTosignBindressTo, int sharedIpGroup, boolean configureServer);
/**
* This operation removes a shared IP address from the specified server.

View File

@ -19,28 +19,58 @@
package org.jclouds.cloudservers.domain;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public class Limits {
private List<RateLimit> rate = Lists.newArrayList();
private List<AbsoluteLimit> absolute = Lists.newArrayList();
private Set<RateLimit> rate = Sets.newLinkedHashSet();
private Map<String, Integer> absolute = Maps.newLinkedHashMap();
public void setRate(List<RateLimit> rate) {
this.rate = rate;
}
public List<RateLimit> getRate() {
public Set<RateLimit> getRate() {
return rate;
}
public void setAbsolute(List<AbsoluteLimit> absolute) {
this.absolute = absolute;
@Override
public String toString() {
return "Limits [rate=" + rate + ", absolute=" + absolute + "]";
}
public List<AbsoluteLimit> getAbsolute() {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((absolute == null) ? 0 : absolute.hashCode());
result = prime * result + ((rate == null) ? 0 : rate.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Limits other = (Limits) obj;
if (absolute == null) {
if (other.absolute != null)
return false;
} else if (!absolute.equals(other.absolute))
return false;
if (rate == null) {
if (other.rate != null)
return false;
} else if (!rate.equals(other.rate))
return false;
return true;
}
public Map<String, Integer> getAbsolute() {
return absolute;
}

View File

@ -19,8 +19,6 @@
package org.jclouds.cloudservers.domain;
import javax.ws.rs.HttpMethod;
/**
*
* RateLimit.
@ -40,16 +38,69 @@ import javax.ws.rs.HttpMethod;
*/
public class RateLimit {
private final String uri;
private final String regex;
private final int remaining;
private final long resetTime;
private final RateLimitUnit unit;
private final int value;
private final HttpMethod verb;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((regex == null) ? 0 : regex.hashCode());
result = prime * result + remaining;
result = prime * result + (int) (resetTime ^ (resetTime >>> 32));
result = prime * result + ((unit == null) ? 0 : unit.hashCode());
result = prime * result + ((uri == null) ? 0 : uri.hashCode());
result = prime * result + value;
result = prime * result + ((verb == null) ? 0 : verb.hashCode());
return result;
}
public RateLimit(String uri, String regex, int remaining, long resetTime, RateLimitUnit unit,
int value, HttpMethod verb) {
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RateLimit other = (RateLimit) obj;
if (regex == null) {
if (other.regex != null)
return false;
} else if (!regex.equals(other.regex))
return false;
if (remaining != other.remaining)
return false;
if (resetTime != other.resetTime)
return false;
if (unit != other.unit)
return false;
if (uri == null) {
if (other.uri != null)
return false;
} else if (!uri.equals(other.uri))
return false;
if (value != other.value)
return false;
if (verb == null) {
if (other.verb != null)
return false;
} else if (!verb.equals(other.verb))
return false;
return true;
}
private String uri;
private String regex;
private int remaining;
private long resetTime;
private RateLimitUnit unit;
private int value;
private String verb;
// for deserializer
public RateLimit() {
}
public RateLimit(String uri, String regex, int remaining, long resetTime, RateLimitUnit unit, int value, String verb) {
this.uri = uri;
this.regex = regex;
this.remaining = remaining;
@ -83,8 +134,14 @@ public class RateLimit {
return value;
}
public HttpMethod getVerb() {
public String getVerb() {
return verb;
}
@Override
public String toString() {
return "[uri=" + uri + ", regex=" + regex + ", remaining=" + remaining + ", resetTime=" + resetTime + ", unit="
+ unit + ", value=" + value + ", verb=" + verb + "]";
}
}

View File

@ -199,6 +199,21 @@ public class CloudServersAsyncClientTest extends RestClientTest<CloudServersAsyn
checkFilters(request);
}
public void testLimits() throws IOException, SecurityException, NoSuchMethodException {
Method method = CloudServersAsyncClient.class.getMethod("getLimits");
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, "GET http://serverManagementUrl/limits?format=json HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Accept: application/json\n");
assertPayloadEquals(request, null, null, false);
assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(request);
}
public void testListServers() throws IOException, SecurityException, NoSuchMethodException {
Method method = CloudServersAsyncClient.class.getMethod("listServers", listOptionsVarargsClass);
HttpRequest request = processor.createRequest(method);

View File

@ -41,6 +41,7 @@ import org.jclouds.cloudservers.domain.DailyBackup;
import org.jclouds.cloudservers.domain.Flavor;
import org.jclouds.cloudservers.domain.Image;
import org.jclouds.cloudservers.domain.ImageStatus;
import org.jclouds.cloudservers.domain.Limits;
import org.jclouds.cloudservers.domain.RebootType;
import org.jclouds.cloudservers.domain.Server;
import org.jclouds.cloudservers.domain.ServerStatus;
@ -92,7 +93,7 @@ public class CloudServersClientLiveTest {
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
+ ".credential");
+ ".credential");
endpoint = System.getProperty("test." + provider + ".endpoint");
apiversion = System.getProperty("test." + provider + ".apiversion");
}
@ -116,8 +117,7 @@ public class CloudServersClientLiveTest {
Properties overrides = setupProperties();
Injector injector = new RestContextFactory().createContextBuilder(provider,
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides)
.buildInjector();
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides).buildInjector();
client = injector.getInstance(CloudServersClient.class);
sshFactory = injector.getInstance(SshClient.Factory.class);
@ -126,6 +126,13 @@ public class CloudServersClientLiveTest {
injector.injectMembers(socketOpen); // add logger
}
public void testLimits() throws Exception {
Limits response = client.getLimits();
assert null != response;
assertTrue(response.getAbsolute().size() > 0);
assertTrue(response.getRate().size() > 0);
}
public void testListServers() throws Exception {
Set<Server> response = client.listServers();
@ -323,8 +330,8 @@ public class CloudServersClientLiveTest {
while (server == null) {
String serverName = serverPrefix + "createserver" + new SecureRandom().nextInt();
try {
server = client.createServer(serverName, imageId, flavorId, withFile("/etc/jclouds.txt",
"rackspace".getBytes()).withMetadata(metadata));
server = client.createServer(serverName, imageId, flavorId,
withFile("/etc/jclouds.txt", "rackspace".getBytes()).withMetadata(metadata));
} catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
if (htpe.getResponse().getStatusCode() == 400)
@ -343,7 +350,7 @@ public class CloudServersClientLiveTest {
private void blockUntilServerActive(int serverId) throws InterruptedException {
Server currentDetails = null;
for (currentDetails = client.getServer(serverId); currentDetails.getStatus() != ServerStatus.ACTIVE; currentDetails = client
.getServer(serverId)) {
.getServer(serverId)) {
System.out.printf("blocking on status active%n%s%n", currentDetails);
Thread.sleep(5 * 1000);
}
@ -352,7 +359,7 @@ public class CloudServersClientLiveTest {
private void blockUntilServerVerifyResize(int serverId) throws InterruptedException {
Server currentDetails = null;
for (currentDetails = client.getServer(serverId); currentDetails.getStatus() != ServerStatus.VERIFY_RESIZE; currentDetails = client
.getServer(serverId)) {
.getServer(serverId)) {
System.out.printf("blocking on status verify resize%n%s%n", currentDetails);
Thread.sleep(5 * 1000);
}
@ -361,7 +368,7 @@ public class CloudServersClientLiveTest {
private void blockUntilImageActive(int imageId) throws InterruptedException {
Image currentDetails = null;
for (currentDetails = client.getImage(imageId); currentDetails.getStatus() != ImageStatus.ACTIVE; currentDetails = client
.getImage(imageId)) {
.getImage(imageId)) {
System.out.printf("blocking on status active%n%s%n", currentDetails);
Thread.sleep(5 * 1000);
}
@ -459,9 +466,12 @@ public class CloudServersClientLiveTest {
while (server == null) {
String serverName = serverPrefix + "createserver" + new SecureRandom().nextInt();
try {
server = client
.createServer(serverName, imageId, flavorId, withFile("/etc/jclouds.txt", "rackspace".getBytes())
.withMetadata(metadata).withSharedIpGroup(sharedIpGroupId).withSharedIp(ip));
server = client.createServer(
serverName,
imageId,
flavorId,
withFile("/etc/jclouds.txt", "rackspace".getBytes()).withMetadata(metadata)
.withSharedIpGroup(sharedIpGroupId).withSharedIp(ip));
} catch (UndeclaredThrowableException e) {
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
if (htpe.getResponse().getStatusCode() == 400)
@ -482,7 +492,7 @@ public class CloudServersClientLiveTest {
try {
ExecResponse response = exec(server, password, "ifconfig -a");
assert response.getOutput().indexOf(ip) > 0 : String.format("server %s didn't get ip %s%n%s", server, ip,
response);
response);
} catch (Exception e) {
e.printStackTrace();
} catch (AssertionError e) {
@ -503,7 +513,7 @@ public class CloudServersClientLiveTest {
try {
ExecResponse response = exec(server, password, "ifconfig -a");
assert response.getOutput().indexOf(ip) == -1 : String.format("server %s still has get ip %s%n%s", server, ip,
response);
response);
} catch (Exception e) {
e.printStackTrace();
} catch (AssertionError e) {
@ -592,7 +602,7 @@ public class CloudServersClientLiveTest {
}
@Test(enabled = false, timeOut = 10 * 60 * 1000, dependsOnMethods = { "testRebootSoft", "testRevertResize",
"testConfirmResize" })
"testConfirmResize" })
void deleteServer2() {
if (serverId2 > 0) {
client.deleteServer(serverId2);