added image support; changed lists to sorted sets in domain objects; added a live test

This commit is contained in:
Alex Yarmula 2010-03-03 14:15:43 -08:00
parent d8d88c3321
commit 202dd690f0
21 changed files with 213 additions and 55 deletions

View File

@ -53,4 +53,9 @@ public interface GoGridAsyncClient {
*/
GridLoadBalancerAsyncClient getLoadBalancerServices();
/**
* @see GoGridClient#getImageServices()
*/
GridImageAsyncClient getImageServices();
}

View File

@ -25,10 +25,7 @@ package org.jclouds.gogrid;
import com.google.inject.ImplementedBy;
import org.jclouds.gogrid.internal.GoGridClientImpl;
import org.jclouds.gogrid.services.GridIpClient;
import org.jclouds.gogrid.services.GridJobClient;
import org.jclouds.gogrid.services.GridLoadBalancerClient;
import org.jclouds.gogrid.services.GridServerClient;
import org.jclouds.gogrid.services.*;
/**
* @author Oleksiy Yarmula
@ -38,27 +35,28 @@ import org.jclouds.gogrid.services.GridServerClient;
public interface GoGridClient {
/**
* Returns methods, related to managing servers
* @return serverServices
* Services with methods, related to managing servers
*/
GridServerClient getServerServices();
/**
* Returns methods, related to retrieving jobs
* @return jobServices
* Services with methods, related to retrieving jobs
*/
GridJobClient getJobServices();
/**
* Returns methods, related to retrieving IP addresses
* @return ipServices
* Services with methods, related to retrieving IP addresses
*/
GridIpClient getIpServices();
/**
* Returns method, related to managing load balancers.
* @return loadBalancerServices
* Services with methods, related to managing load balancers.
*/
GridLoadBalancerClient getLoadBalancerServices();
/**
* Services with methods, related to managing images.
*/
GridImageClient getImageServices();
}

View File

@ -142,6 +142,19 @@ public class GoGridRestClientModule extends AbstractModule {
return SyncProxy.create(GridLoadBalancerClient.class, client);
}
@Provides
@Singleton
protected GridImageAsyncClient provideImageClient(RestClientFactory factory) {
return factory.create(GridImageAsyncClient.class);
}
@Provides
@Singleton
public GridImageClient provideImageClient(GridImageAsyncClient client) throws IllegalArgumentException,
SecurityException, NoSuchMethodException {
return SyncProxy.create(GridImageClient.class, client);
}
@Provides
@Singleton
@GoGrid
@ -167,6 +180,8 @@ public class GoGridRestClientModule extends AbstractModule {
bindings.put(LoadBalancerType.class, new CustomDeserializers.LoadBalancerTypeAdapter());
bindings.put(IpState.class, new CustomDeserializers.IpStateAdapter());
bindings.put(JobState.class, new CustomDeserializers.JobStateAdapter());
bindings.put(ServerImageState.class, new CustomDeserializers.ServerImageStateAdapter());
bindings.put(ServerImageType.class, new CustomDeserializers.ServerImageTypeAdapter());
return bindings;
}

View File

@ -23,10 +23,12 @@
*/
package org.jclouds.gogrid.domain;
import com.google.common.primitives.Longs;
/**
* @author Oleksiy Yarmula
*/
public class BillingToken {
public class BillingToken implements Comparable<BillingToken> {
private long id;
private String name;
@ -80,4 +82,18 @@ public class BillingToken {
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public int compareTo(BillingToken o) {
return Longs.compare(id, o.getId());
}
@Override
public String toString() {
return "BillingToken{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
'}';
}
}

View File

@ -18,10 +18,13 @@
*/
package org.jclouds.gogrid.domain;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
/**
* @author Oleksiy Yarmula
*/
public class IpPortPair {
public class IpPortPair implements Comparable<IpPortPair> {
private Ip ip;
private int port;
@ -64,4 +67,10 @@ public class IpPortPair {
result = 31 * result + port;
return result;
}
@Override
public int compareTo(IpPortPair o) {
if(ip != null && o.getIp() != null) return Longs.compare(ip.getId(), o.getIp().getId());
return Ints.compare(port, o.getPort());
}
}

View File

@ -18,12 +18,13 @@
*/
package org.jclouds.gogrid.domain;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.primitives.Longs;
import com.google.gson.annotations.SerializedName;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
/**
* Represents any job in GoGrid system
@ -46,7 +47,7 @@ public class Job implements Comparable<Job> {
private JobState currentState;
private int attempts;
private String owner;
private List<JobProperties> history;
private SortedSet<JobProperties> history;
@SerializedName("detail") /*NOTE: as of Feb 28, 10,
there is a contradiction b/w the name in
documentation (details) and actual param
@ -61,7 +62,7 @@ public class Job implements Comparable<Job> {
public Job(long id, Option command, ObjectType objectType,
Date createdOn, Date lastUpdatedOn, JobState currentState,
int attempts, String owner, List<JobProperties> history,
int attempts, String owner, SortedSet<JobProperties> history,
Map<String, String> details) {
this.id = id;
this.command = command;
@ -107,8 +108,8 @@ public class Job implements Comparable<Job> {
return owner;
}
public List<JobProperties> getHistory() {
return history;
public SortedSet<JobProperties> getHistory() {
return ImmutableSortedSet.copyOf(history);
}
public Map<String, String> getDetails() {

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.gogrid.domain;
import com.google.common.primitives.Longs;
import com.google.gson.annotations.SerializedName;
import java.util.Date;
@ -29,7 +30,7 @@ import java.util.Date;
*
* @author Oleksiy Yarmula
*/
public class JobProperties {
public class JobProperties implements Comparable<JobProperties> {
private long id;
@SerializedName("updatedon")
@ -100,4 +101,9 @@ public class JobProperties {
", note='" + note + '\'' +
'}';
}
@Override
public int compareTo(JobProperties o) {
return Longs.compare(id, o.getId());
}
}

View File

@ -18,10 +18,11 @@
*/
package org.jclouds.gogrid.domain;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.primitives.Longs;
import com.google.gson.annotations.SerializedName;
import java.util.List;
import java.util.SortedSet;
/**
* @author Oleksiy Yarmula
@ -34,7 +35,7 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
@SerializedName("virtualip")
private IpPortPair virtualIp;
@SerializedName("realiplist")
private List<IpPortPair> realIpList;
private SortedSet<IpPortPair> realIpList;
private LoadBalancerType type;
private LoadBalancerPersistenceType persistence;
private LoadBalancerOs os;
@ -47,7 +48,7 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
}
public LoadBalancer(long id, String name, String description,
IpPortPair virtualIp, List<IpPortPair> realIpList, LoadBalancerType type,
IpPortPair virtualIp, SortedSet<IpPortPair> realIpList, LoadBalancerType type,
LoadBalancerPersistenceType persistence, LoadBalancerOs os,
LoadBalancerState state) {
this.id = id;
@ -77,8 +78,8 @@ public class LoadBalancer implements Comparable<LoadBalancer> {
return virtualIp;
}
public List<IpPortPair> getRealIpList() {
return realIpList;
public SortedSet<IpPortPair> getRealIpList() {
return ImmutableSortedSet.copyOf(realIpList);
}
public LoadBalancerType getType() {

View File

@ -23,16 +23,17 @@
*/
package org.jclouds.gogrid.domain;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.primitives.Longs;
import com.google.gson.annotations.SerializedName;
import java.util.Date;
import java.util.List;
import java.util.SortedSet;
/**
* @author Oleksiy Yarmula
*/
public class ServerImage {
public class ServerImage implements Comparable<ServerImage> {
private long id;
private String name;
@ -40,8 +41,8 @@ public class ServerImage {
private String description;
private Option os;
private Option architecture;
private Option type;
private Option state;
private ServerImageType type;
private ServerImageState state;
private double price;
private String location;
private boolean isActive;
@ -49,7 +50,7 @@ public class ServerImage {
private Date createdTime;
private Date updatedTime;
@SerializedName("billingtokens")
private List<BillingToken> billingTokens;
private SortedSet<BillingToken> billingTokens;
private Customer owner;
/**
@ -60,9 +61,9 @@ public class ServerImage {
public ServerImage(long id, String name, String friendlyName,
String description, Option os, Option architecture,
Option type, Option state, double price, String location,
ServerImageType type, ServerImageState state, double price, String location,
boolean active, boolean aPublic, Date createdTime,
Date updatedTime, List<BillingToken> billingTokens, Customer owner) {
Date updatedTime, SortedSet<BillingToken> billingTokens, Customer owner) {
this.id = id;
this.name = name;
this.friendlyName = friendlyName;
@ -105,11 +106,11 @@ public class ServerImage {
return architecture;
}
public Option getType() {
public ServerImageType getType() {
return type;
}
public Option getState() {
public ServerImageState getState() {
return state;
}
@ -137,8 +138,8 @@ public class ServerImage {
return updatedTime;
}
public List<BillingToken> getBillingTokens() {
return ImmutableList.copyOf(billingTokens);
public SortedSet<BillingToken> getBillingTokens() {
return ImmutableSortedSet.copyOf(billingTokens);
}
public Customer getOwner() {
@ -195,4 +196,31 @@ public class ServerImage {
result = 31 * result + (owner != null ? owner.hashCode() : 0);
return result;
}
@Override
public int compareTo(ServerImage o) {
return Longs.compare(id, o.getId());
}
@Override
public String toString() {
return "ServerImage{" +
"id=" + id +
", name='" + name + '\'' +
", friendlyName='" + friendlyName + '\'' +
", description='" + description + '\'' +
", os=" + os +
", architecture=" + architecture +
", type=" + type +
", state=" + state +
", price=" + price +
", location='" + location + '\'' +
", isActive=" + isActive +
", isPublic=" + isPublic +
", createdTime=" + createdTime +
", updatedTime=" + updatedTime +
", billingTokens=" + billingTokens +
", owner=" + owner +
'}';
}
}

View File

@ -21,7 +21,6 @@ package org.jclouds.gogrid.functions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jclouds.gogrid.domain.Ip;
import org.jclouds.gogrid.domain.Job;
import org.jclouds.gogrid.domain.internal.GenericResponseContainer;
import org.jclouds.http.functions.ParseJson;
@ -37,7 +36,7 @@ import java.util.SortedSet;
*
* @author Oleksiy Yarmula
*/
public class ParseIpListFromJsonResponse extends ParseJson<SortedSet<Ip>> {
public class ParseIpListFromJsonResponse extends ParseJson<SortedSet<Ip>> {
@Inject
public ParseIpListFromJsonResponse(Gson gson) {

View File

@ -84,4 +84,20 @@ public class CustomDeserializers {
}
}
public static class ServerImageStateAdapter implements JsonDeserializer<ServerImageState> {
@Override
public ServerImageState deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
String name = ((JsonObject) jsonElement).get("name").getAsString();
return ServerImageState.fromValue(name);
}
}
public static class ServerImageTypeAdapter implements JsonDeserializer<ServerImageType> {
@Override
public ServerImageType deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
String name = ((JsonObject) jsonElement).get("name").getAsString();
return ServerImageType.fromValue(name);
}
}
}

View File

@ -38,16 +38,19 @@ public class GoGridAsyncClientImpl implements GoGridAsyncClient {
private GridJobAsyncClient gridJobAsyncClient;
private GridIpAsyncClient gridIpAsyncClient;
private GridLoadBalancerAsyncClient gridLoadBalancerAsyncClient;
private GridImageAsyncClient gridImageAsyncClient;
@Inject
public GoGridAsyncClientImpl(GridServerAsyncClient gridServerClient,
GridJobAsyncClient gridJobAsyncClient,
GridIpAsyncClient gridIpAsyncClient,
GridLoadBalancerAsyncClient gridLoadBalancerAsyncClient) {
GridLoadBalancerAsyncClient gridLoadBalancerAsyncClient,
GridImageAsyncClient gridImageAsyncClient) {
this.gridServerAsyncClient = gridServerClient;
this.gridJobAsyncClient = gridJobAsyncClient;
this.gridIpAsyncClient = gridIpAsyncClient;
this.gridLoadBalancerAsyncClient = gridLoadBalancerAsyncClient;
this.gridImageAsyncClient = gridImageAsyncClient;
}
@Override
@ -69,4 +72,9 @@ public class GoGridAsyncClientImpl implements GoGridAsyncClient {
public GridLoadBalancerAsyncClient getLoadBalancerServices() {
return gridLoadBalancerAsyncClient;
}
@Override
public GridImageAsyncClient getImageServices() {
return gridImageAsyncClient;
}
}

View File

@ -38,16 +38,19 @@ public class GoGridClientImpl implements GoGridClient {
private GridJobClient gridJobClient;
private GridIpClient gridIpClient;
private GridLoadBalancerClient gridLoadBalancerClient;
private GridImageClient gridImageClient;
@Inject
public GoGridClientImpl(GridServerClient gridServerClient,
GridJobClient gridJobClient,
GridIpClient gridIpClient,
GridLoadBalancerClient gridLoadBalancerClient) {
GridLoadBalancerClient gridLoadBalancerClient,
GridImageClient gridImageClient) {
this.gridServerClient = gridServerClient;
this.gridJobClient = gridJobClient;
this.gridIpClient = gridIpClient;
this.gridLoadBalancerClient = gridLoadBalancerClient;
this.gridImageClient = gridImageClient;
}
@Override
@ -69,4 +72,9 @@ public class GoGridClientImpl implements GoGridClient {
public GridLoadBalancerClient getLoadBalancerServices() {
return gridLoadBalancerClient;
}
@Override
public GridImageClient getImageServices() {
return gridImageClient;
}
}

View File

@ -55,11 +55,15 @@ public interface GoGridQueryParams {
public static final String IP_STATE_KEY = "ip.state";
public static final String IP_TYPE_KEY = "ip.type";
public static final String LOAD_BALANCER_KEY = "loadbalancer";
public static final String LOAD_BALANCER_TYPE_KEY = "loadbalancer.type";
public static final String LOAD_BALANCER_PERSISTENCE_TYPE_KEY = "loadbalancer.persistence";
public static final String VIRTUAL_IP_KEY = "virtualip.";
public static final String REAL_IP_LIST_KEY = "realiplist.";
public static final String IS_PUBLIC_KEY = "isPublic";
public static final String IMAGE_TYPE_KEY = "image.type";
public static final String IMAGE_STATE_KEY = "image.state";
public static final String IMAGE_FRIENDLY_NAME_KEY = "friendlyName";
public static final String IMAGE_DESCRIPTION_KEY = "description";
}

View File

@ -39,6 +39,8 @@ import static org.jclouds.gogrid.reference.GoGridHeaders.VERSION;
import static org.jclouds.gogrid.reference.GoGridQueryParams.IP_STATE_KEY;
/**
* @see org.jclouds.gogrid.services.GridImageClient
*
* @author Oleksiy Yarmula
*/
@Endpoint(GoGrid.class)

View File

@ -41,6 +41,8 @@ import java.util.Set;
import static org.jclouds.gogrid.reference.GoGridHeaders.VERSION;
import static org.jclouds.gogrid.reference.GoGridQueryParams.ID_KEY;
import static org.jclouds.gogrid.reference.GoGridQueryParams.NAME_KEY;
import static org.jclouds.gogrid.reference.GoGridQueryParams.LOAD_BALANCER_KEY;
/**
* @author Oleksiy Yarmula
@ -80,7 +82,7 @@ public interface GridLoadBalancerAsyncClient {
@GET
@ResponseParser(ParseLoadBalancerFromJsonResponse.class)
@Path("/grid/loadbalancer/add")
ListenableFuture<LoadBalancer> addLoadBalancer(@QueryParam("name") String name,
ListenableFuture<LoadBalancer> addLoadBalancer(@QueryParam(NAME_KEY) String name,
@BinderParam(BindVirtualIpPortPairToQueryParams.class) IpPortPair virtualIp,
@BinderParam(BindRealIpPortPairsToQueryParams.class) List<IpPortPair> realIps,
AddLoadBalancerOptions... options);
@ -91,7 +93,7 @@ public interface GridLoadBalancerAsyncClient {
@GET
@ResponseParser(ParseLoadBalancerFromJsonResponse.class)
@Path("/grid/loadbalancer/edit")
ListenableFuture<LoadBalancer> editLoadBalancer(@QueryParam("loadbalancer") String idOrName,
ListenableFuture<LoadBalancer> editLoadBalancer(@QueryParam(LOAD_BALANCER_KEY) String idOrName,
@BinderParam(BindRealIpPortPairsToQueryParams.class) List<IpPortPair> realIps);
/**

View File

@ -18,19 +18,23 @@
*/
package org.jclouds.gogrid;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.jclouds.gogrid.domain.*;
import org.jclouds.gogrid.options.AddLoadBalancerOptions;
import org.jclouds.gogrid.options.GetImageListOptions;
import org.jclouds.gogrid.options.GetIpListOptions;
import org.jclouds.gogrid.predicates.LoadBalancerLatestJobCompleted;
import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.SkipException;
import org.testng.TestException;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.TimeUnit;
@ -176,7 +180,7 @@ public class GoGridLiveTest {
* Tests common load balancer operations.
* Also verifies IP services and job services.
*/
@Test(enabled=true)
@Test(enabled=false)
public void testLoadBalancerLifecycle() {
int lbCountBeforeTest = client.getLoadBalancerServices().getLoadBalancerList().size();
@ -212,12 +216,12 @@ public class GoGridLiveTest {
assertEquals(createdLoadBalancer.getVirtualIp().getIp().getIp(), vip.getIp());
LoadBalancer editedLoadBalancer = client.getLoadBalancerServices().
editLoadBalancer(nameOfLoadBalancer, Arrays.asList(new IpPortPair(realIp3, 8181)));
editLoadBalancer(nameOfLoadBalancer, Arrays.asList(new IpPortPair(realIp3, 8181)));
assert loadBalancerLatestJobCompleted.apply(editedLoadBalancer);
assertNotNull(editedLoadBalancer.getRealIpList());
assertEquals(editedLoadBalancer.getRealIpList().size(), 1);
assertEquals(Iterables.getOnlyElement(editedLoadBalancer.getRealIpList()).getIp().getIp(), realIp3.getIp());
int lbCountAfterAddingOneServer = client.getLoadBalancerServices().getLoadBalancerList().size();
assert lbCountAfterAddingOneServer == lbCountBeforeTest + 1 :
"There should be +1 increase in the number of load balancers since the test started";
@ -235,6 +239,38 @@ public class GoGridLiveTest {
"There should be the same # of load balancers as since the test started";
}
/**
* Tests common server image operations.
*/
@Test(enabled=true)
public void testImageLifecycle() {
GetImageListOptions options = new GetImageListOptions.Builder().publicDatabaseServers();
Set<ServerImage> images = client.getImageServices().getImageList(options);
Predicate<ServerImage> isDatabaseServer = new Predicate<ServerImage>() {
@Override
public boolean apply(@Nullable ServerImage serverImage) {
return checkNotNull(serverImage).getType() == ServerImageType.DATABASE_SERVER;
}
};
assert Iterables.all(images, isDatabaseServer) : "All of the images should've been of database type";
ServerImage image = Iterables.getLast(images);
ServerImage imageFromServer = Iterables.getOnlyElement(
client.getImageServices().getImagesByName(image.getName()));
assertEquals(image, imageFromServer);
try {
client.getImageServices().editImageDescription(image.getName(), "newDescription");
throw new TestException("An exception hasn't been thrown where expected; expected GoGridResponseException");
} catch(GoGridResponseException e) {
//expected situation - check and proceed
assertTrue(e.getMessage().contains("GoGridIllegalArgumentException"));
}
}
/**
* In case anything went wrong during the tests, removes the objects
* created in the tests.

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.gogrid.functions;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
@ -34,7 +35,6 @@ import org.testng.annotations.Test;
import javax.inject.Singleton;
import java.io.InputStream;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.SortedSet;
@ -70,7 +70,7 @@ public class ParseJobsFromJsonResponseTest {
JobState.SUCCEEDED,
1,
"3116784158f0af2d-24076@api.gogrid.com",
Arrays.asList(
ImmutableSortedSet.of(
new JobProperties(940263L, new Date(1267404528897L),
JobState.CREATED, null),
new JobProperties(940264L, new Date(1267404528967L),

View File

@ -18,6 +18,7 @@
*/
package org.jclouds.gogrid.functions;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
@ -61,7 +62,7 @@ public class ParseLoadBalancersFromJsonResponseTest {
true,
IpState.ASSIGNED),
80),
Arrays.asList(
ImmutableSortedSet.of(
new IpPortPair(new Ip(1313086L,
"204.51.240.185",
"204.51.240.176/255.255.255.240",

View File

@ -32,6 +32,7 @@ import java.util.Date;
import java.util.Map;
import java.util.SortedSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.inject.Provides;
@ -75,13 +76,13 @@ public class ParseServersFromJsonResponseTest {
IpState.ASSIGNED),
new ServerImage(1946L, "GSI-f8979644-e646-4711-ad58-d98a5fa3612c",
"BitNami Gallery 2.3.1-0", "http://bitnami.org/stack/gallery",
centOs, null, webServer,
new Option(2L, "Available", "Image is available for adds"),
centOs, null, ServerImageType.WEB_APPLICATION_SERVER,
ServerImageState.AVAILABLE,
0.0, "24732/GSI-f8979644-e646-4711-ad58-d98a5fa3612c.img",
true, true,
new Date(1261504577971L),
new Date(1262649582180L),
Arrays.asList(
ImmutableSortedSet.of(
new BillingToken(38L, "CentOS 5.2 32bit", 0.0),
new BillingToken(56L, "BitNami: Gallery", 0.0)
),
@ -104,6 +105,8 @@ public class ParseServersFromJsonResponseTest {
public Map<Class, Object> provideCustomAdapterBindings() {
Map<Class, Object> bindings = Maps.newHashMap();
bindings.put(IpState.class, new CustomDeserializers.IpStateAdapter());
bindings.put(ServerImageType.class, new CustomDeserializers.ServerImageTypeAdapter());
bindings.put(ServerImageState.class, new CustomDeserializers.ServerImageStateAdapter());
return bindings;
}
});

View File

@ -47,7 +47,7 @@ public class HttpCommandMock implements HttpCommand {
}
@Override
public void changeHostAndPortTo(String host, int port) {
public void changeSchemeHostAndPortTo(String scheme, String host, int port) {
}
@Override