mirror of https://github.com/apache/jclouds.git
Issue 77: more support on cloud servers including password change
git-svn-id: http://jclouds.googlecode.com/svn/trunk@1654 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
3d5d31f037
commit
3c0547c7df
|
@ -60,8 +60,8 @@ public class JschSshConnection implements SshConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkConnected() {
|
private void checkConnected() {
|
||||||
checkState(sftp.isConnected(), String.format("%s@%s:%d: SFTP not connected!", username, host
|
checkState(sftp != null && sftp.isConnected(), String.format("%s@%s:%d: SFTP not connected!",
|
||||||
.getHostAddress(), port));
|
username, host.getHostAddress(), port));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
|
|
|
@ -30,10 +30,13 @@ import java.util.concurrent.Future;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.http.functions.ReturnFalseOn404;
|
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||||
|
import org.jclouds.rackspace.cloudservers.binders.ChangeAdminPassBinder;
|
||||||
|
import org.jclouds.rackspace.cloudservers.binders.ChangeServerNameBinder;
|
||||||
import org.jclouds.rackspace.cloudservers.domain.Flavor;
|
import org.jclouds.rackspace.cloudservers.domain.Flavor;
|
||||||
import org.jclouds.rackspace.cloudservers.domain.Image;
|
import org.jclouds.rackspace.cloudservers.domain.Image;
|
||||||
import org.jclouds.rackspace.cloudservers.domain.Server;
|
import org.jclouds.rackspace.cloudservers.domain.Server;
|
||||||
|
@ -47,7 +50,9 @@ import org.jclouds.rackspace.cloudservers.functions.ReturnFlavorNotFoundOn404;
|
||||||
import org.jclouds.rackspace.cloudservers.functions.ReturnImageNotFoundOn404;
|
import org.jclouds.rackspace.cloudservers.functions.ReturnImageNotFoundOn404;
|
||||||
import org.jclouds.rackspace.cloudservers.functions.ReturnServerNotFoundOn404;
|
import org.jclouds.rackspace.cloudservers.functions.ReturnServerNotFoundOn404;
|
||||||
import org.jclouds.rackspace.cloudservers.options.CreateServerOptions;
|
import org.jclouds.rackspace.cloudservers.options.CreateServerOptions;
|
||||||
|
import org.jclouds.rackspace.cloudservers.options.ListOptions;
|
||||||
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
import org.jclouds.rackspace.filters.AuthenticateRequest;
|
||||||
|
import org.jclouds.rest.EntityParam;
|
||||||
import org.jclouds.rest.ExceptionParser;
|
import org.jclouds.rest.ExceptionParser;
|
||||||
import org.jclouds.rest.PostBinder;
|
import org.jclouds.rest.PostBinder;
|
||||||
import org.jclouds.rest.PostParam;
|
import org.jclouds.rest.PostParam;
|
||||||
|
@ -73,7 +78,11 @@ public interface CloudServersConnection {
|
||||||
*
|
*
|
||||||
* List all servers (IDs and names only)
|
* List all servers (IDs and names only)
|
||||||
*
|
*
|
||||||
* @see #listServerDetails()
|
* This operation provides a list of servers associated with your account. 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()}
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@ResponseParser(ParseServerListFromGsonResponse.class)
|
@ResponseParser(ParseServerListFromGsonResponse.class)
|
||||||
|
@ -81,24 +90,13 @@ public interface CloudServersConnection {
|
||||||
@Path("/servers")
|
@Path("/servers")
|
||||||
// TODO: Error Response Code(s): cloudServersFault (400, 500), serviceUnavailable (503),
|
// TODO: Error Response Code(s): cloudServersFault (400, 500), serviceUnavailable (503),
|
||||||
// unauthorized (401), badRequest (400), overLimit (413)
|
// unauthorized (401), badRequest (400), overLimit (413)
|
||||||
List<Server> listServers();
|
List<Server> listServers(ListOptions... options);
|
||||||
|
|
||||||
/**
|
|
||||||
* This operation provides a list of servers associated with your account. Servers that have been
|
|
||||||
* deleted are not included in this list.
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@ResponseParser(ParseServerListFromGsonResponse.class)
|
|
||||||
@Query(key = "format", value = "json")
|
|
||||||
@Path("/servers/detail")
|
|
||||||
// TODO: Error Response Code(s): cloudServersFault (400, 500), serviceUnavailable (503),
|
|
||||||
// unauthorized (401), badRequest (400), overLimit (413)
|
|
||||||
List<Server> listServerDetails();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* This operation returns details of the specified server.
|
* This operation returns details of the specified server.
|
||||||
*
|
*
|
||||||
|
* @return {@link Server#NOT_FOUND} if the server is not found
|
||||||
* @see Server
|
* @see Server
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
|
@ -108,7 +106,7 @@ public interface CloudServersConnection {
|
||||||
@Path("/servers/{id}")
|
@Path("/servers/{id}")
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400)
|
// (400)
|
||||||
Server getServerDetails(@PathParam("id") int id);
|
Server getServer(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -116,7 +114,7 @@ public interface CloudServersConnection {
|
||||||
* <p/>
|
* <p/>
|
||||||
* Note: When a server is deleted, all images created from that server are also removed.
|
* Note: When a server is deleted, all images created from that server are also removed.
|
||||||
*
|
*
|
||||||
*
|
* @return false if the server is not found
|
||||||
* @see Server
|
* @see Server
|
||||||
*/
|
*/
|
||||||
@DELETE
|
@DELETE
|
||||||
|
@ -126,6 +124,25 @@ public interface CloudServersConnection {
|
||||||
// (400), itemNotFound (404), buildInProgress (409), overLimit (413)
|
// (400), itemNotFound (404), buildInProgress (409), overLimit (413)
|
||||||
boolean deleteServer(@PathParam("id") int id);
|
boolean deleteServer(@PathParam("id") int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reboot function allows for either a soft or hard reboot of a server. With a soft reboot,
|
||||||
|
* the operating system is signaled to restart, which allows for a graceful shutdown of all
|
||||||
|
* processes. A hard reboot is the equivalent of power cycling the server.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The rebuild function removes all data on the server and replaces it with the specified image.
|
||||||
|
* Server ID and IP addresses remain the same.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resize function converts an existing server to a different flavor, in essence, scaling the
|
||||||
|
* server up or down. The original server is saved for a period of time to allow rollback if
|
||||||
|
* there is a problem. All resizes should be tested and explicitly confirmed, at which time the
|
||||||
|
* original server is removed. All resizes are automatically confirmed after 24 hours if they are
|
||||||
|
* not confirmed or reverted.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This operation asynchronously provisions a new server. The progress of this operation depends
|
* This operation asynchronously provisions a new server. The progress of this operation depends
|
||||||
* on several factors including location of the requested image, network i/o, host load, and the
|
* on several factors including location of the requested image, network i/o, host load, and the
|
||||||
|
@ -133,6 +150,9 @@ public interface CloudServersConnection {
|
||||||
* which will return a progress attribute (0-100% completion). A password will be randomly
|
* which will return a progress attribute (0-100% completion). A password will be randomly
|
||||||
* generated for you and returned in the response object. For security reasons, it will not be
|
* generated for you and returned in the response object. For security reasons, it will not be
|
||||||
* returned in subsequent GET calls against a given server ID.
|
* returned in subsequent GET calls against a given server ID.
|
||||||
|
*
|
||||||
|
* @param options
|
||||||
|
* - used to specify extra files, metadata, or ip parameters during server creation.
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@ResponseParser(ParseServerFromGsonResponse.class)
|
@ResponseParser(ParseServerFromGsonResponse.class)
|
||||||
|
@ -142,13 +162,45 @@ public interface CloudServersConnection {
|
||||||
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401),
|
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401),
|
||||||
// badMediaType(415), badRequest (400), serverCapacityUnavailable (503), overLimit (413)
|
// badMediaType(415), badRequest (400), serverCapacityUnavailable (503), overLimit (413)
|
||||||
Server createServer(@PostParam("name") String name, @PostParam("imageId") int imageId,
|
Server createServer(@PostParam("name") String name, @PostParam("imageId") int imageId,
|
||||||
@PostParam("flavorId") int flavorId);
|
@PostParam("flavorId") int flavorId, CreateServerOptions... options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This operation allows you to change the administrative password.
|
||||||
|
* <p/>
|
||||||
|
* Status Transition: ACTIVE - PASSWORD - ACTIVE
|
||||||
|
*
|
||||||
|
* @return false if the server is not found
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@ExceptionParser(ReturnFalseOn404.class)
|
||||||
|
@Path("/servers/{id}")
|
||||||
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
|
// (400), badMediaType(415), buildInProgress (409), overLimit (413)
|
||||||
|
boolean changeAdminPass(@PathParam("id") int id,
|
||||||
|
@EntityParam(ChangeAdminPassBinder.class) String adminPass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This operation allows you to update the name of the server. This operation changes the name of
|
||||||
|
* the server in the Cloud Servers system and does not change the server host name itself.
|
||||||
|
* <p/>
|
||||||
|
* Status Transition: ACTIVE - PASSWORD - ACTIVE
|
||||||
|
*
|
||||||
|
* @return false if the server is not found
|
||||||
|
*/
|
||||||
|
@PUT
|
||||||
|
@ExceptionParser(ReturnFalseOn404.class)
|
||||||
|
@Path("/servers/{id}")
|
||||||
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
|
// (400), badMediaType(415), buildInProgress (409), overLimit (413)
|
||||||
|
boolean renameServer(@PathParam("id") int id,
|
||||||
|
@EntityParam(ChangeServerNameBinder.class) String newName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* List available flavors (IDs and names only)
|
* List available flavors (IDs and names only)
|
||||||
*
|
*
|
||||||
* @see #listFlavorDetails()
|
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
|
||||||
|
* withDetails()}
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@ResponseParser(ParseFlavorListFromGsonResponse.class)
|
@ResponseParser(ParseFlavorListFromGsonResponse.class)
|
||||||
|
@ -156,27 +208,14 @@ public interface CloudServersConnection {
|
||||||
@Path("/flavors")
|
@Path("/flavors")
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400)
|
// (400)
|
||||||
List<Flavor> listFlavors();
|
List<Flavor> listFlavors(ListOptions... options);
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* List available flavors (all details)
|
|
||||||
*
|
|
||||||
* @see Flavor
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@ResponseParser(ParseFlavorListFromGsonResponse.class)
|
|
||||||
@Query(key = "format", value = "json")
|
|
||||||
@Path("/flavors/detail")
|
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
|
||||||
// (400)
|
|
||||||
List<Flavor> listFlavorDetails();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* List available images (IDs and names only)
|
* List available images (IDs and names only)
|
||||||
*
|
*
|
||||||
* @see #listImageDetails()
|
* in order to retrieve all details, pass the option {@link ListOptions#withDetails()
|
||||||
|
* withDetails()}
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@ResponseParser(ParseImageListFromGsonResponse.class)
|
@ResponseParser(ParseImageListFromGsonResponse.class)
|
||||||
|
@ -184,26 +223,13 @@ public interface CloudServersConnection {
|
||||||
@Path("/images")
|
@Path("/images")
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400)
|
// (400)
|
||||||
List<Image> listImages();
|
List<Image> listImages(ListOptions... options);
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* This operation will list all images visible by the account.
|
|
||||||
*
|
|
||||||
* @see Image
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@ResponseParser(ParseImageListFromGsonResponse.class)
|
|
||||||
@Query(key = "format", value = "json")
|
|
||||||
@Path("/images/detail")
|
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
|
||||||
// (400)
|
|
||||||
List<Image> listImageDetails();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* This operation returns details of the specified image.
|
* This operation returns details of the specified image.
|
||||||
*
|
*
|
||||||
|
* @return {@link Image#NOT_FOUND} if the image is not found
|
||||||
* @see Image
|
* @see Image
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
|
@ -213,12 +239,13 @@ public interface CloudServersConnection {
|
||||||
@Path("/images/{id}")
|
@Path("/images/{id}")
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400)
|
// (400)
|
||||||
Image getImageDetails(@PathParam("id") int id);
|
Image getImage(@PathParam("id") int id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* This operation returns details of the specified flavor.
|
* This operation returns details of the specified flavor.
|
||||||
*
|
*
|
||||||
|
* @return {@link Flavor#NOT_FOUND} if the flavor is not found
|
||||||
* @see Flavor
|
* @see Flavor
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
|
@ -228,6 +255,6 @@ public interface CloudServersConnection {
|
||||||
@Path("/flavors/{id}")
|
@Path("/flavors/{id}")
|
||||||
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
|
||||||
// (400)
|
// (400)
|
||||||
Flavor getFlavorDetails(@PathParam("id") int id);
|
Flavor getFlavor(@PathParam("id") int id);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.jclouds.rackspace.cloudservers.binders;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.binders.JsonBinder;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ChangeAdminPassBinder extends JsonBinder {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
||||||
|
throw new IllegalStateException("Change Admin Pass is a PUT operation");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
||||||
|
checkArgument(toBind instanceof String, "this binder is only valid for Strings!");
|
||||||
|
super.addEntityToRequest(ImmutableMap.of("server", ImmutableMap.of("adminPass", checkNotNull(
|
||||||
|
toBind, "adminPass"))), request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package org.jclouds.rackspace.cloudservers.binders;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.binders.JsonBinder;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ChangeServerNameBinder extends JsonBinder {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
|
||||||
|
throw new IllegalStateException("Change Server Name is a PUT operation");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addEntityToRequest(Object toBind, HttpRequest request) {
|
||||||
|
checkArgument(toBind instanceof String, "this binder is only valid for Strings!");
|
||||||
|
super.addEntityToRequest(ImmutableMap.of("server", ImmutableMap.of("name", checkNotNull(
|
||||||
|
toBind, "name"))), request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,12 +23,18 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudservers.domain;
|
package org.jclouds.rackspace.cloudservers.domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A backup schedule can be defined to create server images at regular intervals (daily and weekly).
|
||||||
|
* Backup schedules are configurable per server.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
public class BackupSchedule {
|
public class BackupSchedule {
|
||||||
|
|
||||||
protected DailyBackup daily;
|
protected DailyBackup daily;
|
||||||
protected boolean enabled;
|
protected boolean enabled;
|
||||||
protected String weekly;
|
protected String weekly;
|
||||||
|
|
||||||
public DailyBackup getDaily() {
|
public DailyBackup getDaily() {
|
||||||
return daily;
|
return daily;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +46,7 @@ public class BackupSchedule {
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEnabled(boolean value) {
|
public void setEnabled(boolean value) {
|
||||||
this.enabled = value;
|
this.enabled = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ package org.jclouds.rackspace.cloudservers.domain;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* A flavor is an available hardware configuration for a server. Each flavor has a unique
|
* A flavor is an available hardware configuration for a server. Each flavor has a unique
|
||||||
* combination of disk space, memory capacity.
|
* combination of disk space and memory capacity.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,15 +26,17 @@ package org.jclouds.rackspace.cloudservers.domain;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An image is a collection of files you use to create or rebuild a server. Rackspace provides
|
* An image is a collection of files used to create or rebuild a server. Rackspace provides a number
|
||||||
* pre-built OS images by default. You may also create custom images.
|
* of pre-built OS images by default. You may also create custom images from cloud servers you have
|
||||||
|
* launched. These custom images are useful for backup purposes or for producing ÒgoldÓ server
|
||||||
|
* images if you plan to deploy a particular server configuration frequently.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class Image {
|
public class Image {
|
||||||
|
|
||||||
public static final Image NOT_FOUND = new Image(-1,"NOT_FOUND");
|
public static final Image NOT_FOUND = new Image(-1, "NOT_FOUND");
|
||||||
|
|
||||||
private DateTime created;
|
private DateTime created;
|
||||||
private int id;
|
private int id;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
|
@ -28,8 +28,8 @@ import java.util.Map;
|
||||||
import com.google.inject.internal.Maps;
|
import com.google.inject.internal.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* A server is a virtual machine instance in the Cloud Servers system. Flavor and image are
|
||||||
* Server.
|
* requisite elements when creating a server.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
|
|
|
@ -117,6 +117,12 @@ public class CreateServerOptions extends JsonBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A shared IP group is a collection of servers that can share IPs with other members of the
|
||||||
|
* group. Any server in a group can share one or more public IPs with any other server in the
|
||||||
|
* group. With the exception of the first server in a shared IP group, servers must be launched
|
||||||
|
* into shared IP groups. A server may only be a member of one shared IP group.
|
||||||
|
*
|
||||||
|
* <p/>
|
||||||
* Servers in the same shared IP group can share public IPs for various high availability and
|
* Servers in the same shared IP group can share public IPs for various high availability and
|
||||||
* load balancing configurations. To launch an HA server, include the optional sharedIpGroupId
|
* load balancing configurations. To launch an HA server, include the optional sharedIpGroupId
|
||||||
* element and the server will be launched into that shared IP group.
|
* element and the server will be launched into that shared IP group.
|
||||||
|
@ -160,6 +166,14 @@ public class CreateServerOptions extends JsonBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Public IP addresses can be shared across multiple servers for use in various high availability
|
||||||
|
* scenarios. When an IP address is shared to another server, the cloud network restrictions are
|
||||||
|
* modified to allow each server to listen to and respond on that IP address (you may optionally
|
||||||
|
* specify that the target server network configuration be modified). Shared IP addresses can be
|
||||||
|
* used with many standard heartbeat facilities (e.g. keepalived) that monitor for failure and
|
||||||
|
* manage IP failover.
|
||||||
|
*
|
||||||
|
* <p/>
|
||||||
* If you intend to use a shared IP on the server being created and have no need for a separate
|
* If you intend to use a shared IP on the server being created and have no need for a separate
|
||||||
* public IP address, you may launch the server into a shared IP group and specify an IP address
|
* public IP address, you may launch the server into a shared IP group and specify an IP address
|
||||||
* from that shared IP group to be used as its public IP. You can accomplish this by specifying
|
* from that shared IP group to be used as its public IP. You can accomplish this by specifying
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
package org.jclouds.rackspace.cloudservers.options;
|
||||||
|
|
||||||
|
import org.jclouds.rackspace.options.BaseListOptions;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options used to control the amount of detail in the request.
|
||||||
|
*
|
||||||
|
* @see BaseListOptions
|
||||||
|
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class ListOptions extends BaseListOptions {
|
||||||
|
|
||||||
|
public static final ListOptions NONE = new ListOptions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unless used, only the name and id will be returned per row.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ListOptions withDetails() {
|
||||||
|
this.pathSuffix = "/detail";
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ListOptions changesSince(DateTime ifModifiedSince) {
|
||||||
|
super.changesSince(ifModifiedSince);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ListOptions maxResults(int limit) {
|
||||||
|
super.maxResults(limit);
|
||||||
|
return this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ListOptions startAt(long offset) {
|
||||||
|
super.startAt(offset);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ListOptions#withDetails()
|
||||||
|
*/
|
||||||
|
public static ListOptions withDetails() {
|
||||||
|
ListOptions options = new ListOptions();
|
||||||
|
return options.withDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BaseListOptions#startAt(long)
|
||||||
|
*/
|
||||||
|
public static ListOptions startAt(long prefix) {
|
||||||
|
ListOptions options = new ListOptions();
|
||||||
|
return options.startAt(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BaseListOptions#maxResults(long)
|
||||||
|
*/
|
||||||
|
public static ListOptions maxResults(int maxKeys) {
|
||||||
|
ListOptions options = new ListOptions();
|
||||||
|
return options.maxResults(maxKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BaseListOptions#changesSince(DateTime)
|
||||||
|
*/
|
||||||
|
public static ListOptions changesSince(DateTime since) {
|
||||||
|
ListOptions options = new ListOptions();
|
||||||
|
return options.changesSince(since);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,15 +23,22 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudservers;
|
package org.jclouds.rackspace.cloudservers;
|
||||||
|
|
||||||
|
import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withFile;
|
||||||
|
import static org.jclouds.rackspace.cloudservers.options.ListOptions.Builder.withDetails;
|
||||||
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_KEY;
|
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_KEY;
|
||||||
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_USER;
|
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_USER;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rackspace.cloudservers.domain.Flavor;
|
import org.jclouds.rackspace.cloudservers.domain.Flavor;
|
||||||
import org.jclouds.rackspace.cloudservers.domain.Image;
|
import org.jclouds.rackspace.cloudservers.domain.Image;
|
||||||
|
@ -43,6 +50,7 @@ import org.jclouds.util.Utils;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,13 +58,13 @@ import com.google.inject.Injector;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "cloudservers.CloudServersConnectionLiveTest")
|
@Test(groups = "live", sequential = true, testName = "cloudservers.CloudServersConnectionLiveTest")
|
||||||
public class CloudServersConnectionLiveTest {
|
public class CloudServersConnectionLiveTest {
|
||||||
|
|
||||||
protected static final String sysRackspaceUser = System.getProperty(PROPERTY_RACKSPACE_USER);
|
protected static final String sysRackspaceUser = System.getProperty(PROPERTY_RACKSPACE_USER);
|
||||||
protected static final String sysRackspaceKey = System.getProperty(PROPERTY_RACKSPACE_KEY);
|
protected static final String sysRackspaceKey = System.getProperty(PROPERTY_RACKSPACE_KEY);
|
||||||
CloudServersConnection connection;
|
protected CloudServersConnection connection;
|
||||||
SshConnection.Factory sshFactory;
|
protected SshConnection.Factory sshFactory;
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupConnection() {
|
public void setupConnection() {
|
||||||
|
@ -80,7 +88,7 @@ public class CloudServersConnectionLiveTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListServersDetail() throws Exception {
|
public void testListServersDetail() throws Exception {
|
||||||
List<Server> response = connection.listServerDetails();
|
List<Server> response = connection.listServers(withDetails());
|
||||||
assert null != response;
|
assert null != response;
|
||||||
long initialContainerCount = response.size();
|
long initialContainerCount = response.size();
|
||||||
assertTrue(initialContainerCount >= 0);
|
assertTrue(initialContainerCount >= 0);
|
||||||
|
@ -101,7 +109,7 @@ public class CloudServersConnectionLiveTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListFlavorsDetail() throws Exception {
|
public void testListFlavorsDetail() throws Exception {
|
||||||
List<Flavor> response = connection.listFlavorDetails();
|
List<Flavor> response = connection.listFlavors(withDetails());
|
||||||
assert null != response;
|
assert null != response;
|
||||||
long flavorCount = response.size();
|
long flavorCount = response.size();
|
||||||
assertTrue(flavorCount >= 0);
|
assertTrue(flavorCount >= 0);
|
||||||
|
@ -128,7 +136,7 @@ public class CloudServersConnectionLiveTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListImagesDetail() throws Exception {
|
public void testListImagesDetail() throws Exception {
|
||||||
List<Image> response = connection.listImageDetails();
|
List<Image> response = connection.listImages(withDetails());
|
||||||
assert null != response;
|
assert null != response;
|
||||||
long imageCount = response.size();
|
long imageCount = response.size();
|
||||||
assertTrue(imageCount >= 0);
|
assertTrue(imageCount >= 0);
|
||||||
|
@ -144,13 +152,13 @@ public class CloudServersConnectionLiveTest {
|
||||||
|
|
||||||
@Test(enabled = false)
|
@Test(enabled = false)
|
||||||
// Rackspace Web Hosting issue #118856
|
// Rackspace Web Hosting issue #118856
|
||||||
public void testGetImageDetails() throws Exception {
|
public void testGetImagesDetail() throws Exception {
|
||||||
List<Image> response = connection.listImageDetails();
|
List<Image> response = connection.listImages(withDetails());
|
||||||
assert null != response;
|
assert null != response;
|
||||||
long imageCount = response.size();
|
long imageCount = response.size();
|
||||||
assertTrue(imageCount >= 0);
|
assertTrue(imageCount >= 0);
|
||||||
for (Image image : response) {
|
for (Image image : response) {
|
||||||
Image newDetails = connection.getImageDetails(image.getId());
|
Image newDetails = connection.getImage(image.getId());
|
||||||
assertEquals(image, newDetails);
|
assertEquals(image, newDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,79 +166,147 @@ public class CloudServersConnectionLiveTest {
|
||||||
@Test(enabled = false)
|
@Test(enabled = false)
|
||||||
// Rackspace Web Hosting issue #118856
|
// Rackspace Web Hosting issue #118856
|
||||||
public void testGetImageDetailsNotFound() throws Exception {
|
public void testGetImageDetailsNotFound() throws Exception {
|
||||||
Image newDetails = connection.getImageDetails(12312987);
|
Image newDetails = connection.getImage(12312987);
|
||||||
assertEquals(Image.NOT_FOUND, newDetails);
|
assertEquals(Image.NOT_FOUND, newDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetFlavorDetails() throws Exception {
|
public void testGetFlavorsDetail() throws Exception {
|
||||||
List<Flavor> response = connection.listFlavorDetails();
|
List<Flavor> response = connection.listFlavors(withDetails());
|
||||||
assert null != response;
|
assert null != response;
|
||||||
long flavorCount = response.size();
|
long flavorCount = response.size();
|
||||||
assertTrue(flavorCount >= 0);
|
assertTrue(flavorCount >= 0);
|
||||||
for (Flavor flavor : response) {
|
for (Flavor flavor : response) {
|
||||||
Flavor newDetails = connection.getFlavorDetails(flavor.getId());
|
Flavor newDetails = connection.getFlavor(flavor.getId());
|
||||||
assertEquals(flavor, newDetails);
|
assertEquals(flavor, newDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetFlavorDetailsNotFound() throws Exception {
|
public void testGetFlavorDetailsNotFound() throws Exception {
|
||||||
Flavor newDetails = connection.getFlavorDetails(12312987);
|
Flavor newDetails = connection.getFlavor(12312987);
|
||||||
assertEquals(Flavor.NOT_FOUND, newDetails);
|
assertEquals(Flavor.NOT_FOUND, newDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetServerDetailsNotFound() throws Exception {
|
public void testGetServerDetailsNotFound() throws Exception {
|
||||||
Server newDetails = connection.getServerDetails(12312987);
|
Server newDetails = connection.getServer(12312987);
|
||||||
assertEquals(Server.NOT_FOUND, newDetails);
|
assertEquals(Server.NOT_FOUND, newDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetServerDetails() throws Exception {
|
public void testGetServersDetail() throws Exception {
|
||||||
List<Server> response = connection.listServerDetails();
|
List<Server> response = connection.listServers(withDetails());
|
||||||
assert null != response;
|
assert null != response;
|
||||||
long serverCount = response.size();
|
long serverCount = response.size();
|
||||||
assertTrue(serverCount >= 0);
|
assertTrue(serverCount >= 0);
|
||||||
for (Server server : response) {
|
for (Server server : response) {
|
||||||
Server newDetails = connection.getServerDetails(server.getId());
|
Server newDetails = connection.getServer(server.getId());
|
||||||
assertEquals(server, newDetails);
|
assertEquals(server, newDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String serverPrefix = System.getProperty("user.name") + ".cs";
|
private String serverPrefix = System.getProperty("user.name") + ".cs";
|
||||||
|
private int serverId;
|
||||||
|
private String adminPass;
|
||||||
|
Map<String, String> metadata = ImmutableMap.of("jclouds", "rackspace");
|
||||||
|
|
||||||
@Test(timeOut = 5 * 60 * 1000)
|
@Test(timeOut = 5 * 60 * 1000)
|
||||||
public void testCreateServer() throws Exception {
|
public void testCreateServer() throws Exception {
|
||||||
Server newDetails = connection.createServer(serverPrefix + "createserver", 2, 1);
|
int imageId = 2;
|
||||||
System.err.print(newDetails);
|
int flavorId = 1;
|
||||||
assertNotNull(newDetails.getAdminPass());
|
Server server = null;
|
||||||
assertNotNull(newDetails.getHostId());
|
while (server == null) {
|
||||||
assertEquals(newDetails.getStatus(), ServerStatus.BUILD);
|
String serverName = serverPrefix + "createserver" + new SecureRandom().nextInt();
|
||||||
assert newDetails.getProgress() >= 0 : "newDetails.getProgress()" + newDetails.getProgress();
|
try {
|
||||||
assertEquals(new Integer(2), newDetails.getImageId());
|
server = connection.createServer(serverName, imageId, flavorId, withFile(
|
||||||
assertEquals(new Integer(1), newDetails.getFlavorId());
|
"/etc/jclouds.txt", "rackspace".getBytes()).withMetadata(metadata));
|
||||||
assertNotNull(newDetails.getAddresses());
|
} catch (UndeclaredThrowableException e) {
|
||||||
assertEquals(newDetails.getAddresses().getPublicAddresses().size(), 1);
|
HttpResponseException htpe = (HttpResponseException) e.getCause().getCause();
|
||||||
assertEquals(newDetails.getAddresses().getPrivateAddresses().size(), 1);
|
if (htpe.getResponse().getStatusCode() == 400)
|
||||||
|
continue;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertNotNull(server.getAdminPass());
|
||||||
|
serverId = server.getId();
|
||||||
|
adminPass = server.getAdminPass();
|
||||||
|
assertEquals(server.getStatus(), ServerStatus.BUILD);
|
||||||
|
blockUntilActive(server);
|
||||||
|
}
|
||||||
|
|
||||||
int serverId = newDetails.getId();
|
private void blockUntilActive(Server server) throws InterruptedException {
|
||||||
ServerStatus currentStatus = newDetails.getStatus();
|
ServerStatus currentStatus = server.getStatus();
|
||||||
Server currentDetails = newDetails;
|
Server currentDetails = server;
|
||||||
while (currentStatus != ServerStatus.ACTIVE) {
|
while (currentStatus != ServerStatus.ACTIVE) {
|
||||||
Thread.sleep(5 * 1000);
|
Thread.sleep(5 * 1000);
|
||||||
currentDetails = connection.getServerDetails(serverId);
|
currentDetails = connection.getServer(serverId);
|
||||||
System.out.println(currentDetails);
|
System.out.println(currentDetails);
|
||||||
currentStatus = currentDetails.getStatus();
|
currentStatus = currentDetails.getStatus();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InputStream etcPasswd = sshFactory.create(
|
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServer")
|
||||||
newDetails.getAddresses().getPublicAddresses().get(0), 22, "root",
|
public void testServerDetails() throws Exception {
|
||||||
newDetails.getAdminPass()).get("/etc/passwd");
|
Server server = connection.getServer(serverId);
|
||||||
String etcPasswdContents = Utils.toStringAndClose(etcPasswd);
|
|
||||||
assert etcPasswdContents.indexOf("root") >= 0 : etcPasswdContents;
|
|
||||||
|
|
||||||
connection.deleteServer(serverId);
|
assertNotNull(server.getHostId());
|
||||||
|
assertEquals(server.getStatus(), ServerStatus.ACTIVE);
|
||||||
|
assert server.getProgress() >= 0 : "newDetails.getProgress()" + server.getProgress();
|
||||||
|
assertEquals(new Integer(2), server.getImageId());
|
||||||
|
assertEquals(new Integer(1), server.getFlavorId());
|
||||||
|
assertNotNull(server.getAddresses());
|
||||||
|
assertEquals(server.getAddresses().getPublicAddresses().size(), 1);
|
||||||
|
assertEquals(server.getAddresses().getPrivateAddresses().size(), 1);
|
||||||
|
|
||||||
currentDetails = connection.getServerDetails(serverId);
|
// check metadata
|
||||||
assertEquals(ServerStatus.DELETED, currentDetails.getStatus());
|
assertEquals(server.getMetadata(), metadata);
|
||||||
|
checkPassOk(server, adminPass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this tests "personality" as the file looked up was sent during server creation
|
||||||
|
*/
|
||||||
|
private void checkPassOk(Server newDetails, String pass) throws IOException {
|
||||||
|
SshConnection connection = sshFactory.create(newDetails.getAddresses().getPublicAddresses()
|
||||||
|
.get(0), 22, "root", pass);
|
||||||
|
try {
|
||||||
|
connection.connect();
|
||||||
|
InputStream etcPasswd = connection.get("/etc/jclouds.txt");
|
||||||
|
String etcPasswdContents = Utils.toStringAndClose(etcPasswd);
|
||||||
|
assertEquals("rackspace", etcPasswdContents.trim());
|
||||||
|
} finally {
|
||||||
|
if (connection != null)
|
||||||
|
connection.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServer")
|
||||||
|
public void testRenameServer() throws Exception {
|
||||||
|
Server server = connection.getServer(serverId);
|
||||||
|
String oldName = server.getName();
|
||||||
|
assertTrue(connection.renameServer(serverId, oldName + "new"));
|
||||||
|
blockUntilActive(server);
|
||||||
|
assertEquals(oldName + "new", connection.getServer(serverId).getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateServer")
|
||||||
|
public void testChangePassword() throws Exception {
|
||||||
|
Server server = connection.getServer(serverId);
|
||||||
|
assertTrue(connection.changeAdminPass(serverId, "elmo"));
|
||||||
|
blockUntilActive(server);
|
||||||
|
checkPassOk(connection.getServer(serverId), "elmo");
|
||||||
|
this.adminPass = "elmo";
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO test createServer.withSharedIpGroup
|
||||||
|
// TODO test createServer.withSharedIp
|
||||||
|
|
||||||
|
// must be last!
|
||||||
|
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = {"testChangePassword","testRenameServer"})
|
||||||
|
void deleteServer() {
|
||||||
|
if (serverId > 0) {
|
||||||
|
connection.deleteServer(serverId);
|
||||||
|
Server server = connection.getServer(serverId);
|
||||||
|
assertEquals(server, Server.NOT_FOUND);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,17 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rackspace.cloudservers;
|
package org.jclouds.rackspace.cloudservers;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withFile;
|
||||||
|
import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withMetadata;
|
||||||
|
import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withSharedIpGroup;
|
||||||
|
import static org.jclouds.rackspace.cloudservers.options.ListOptions.Builder.changesSince;
|
||||||
|
import static org.jclouds.rackspace.cloudservers.options.ListOptions.Builder.withDetails;
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
@ -37,6 +44,8 @@ import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
import org.jclouds.http.HttpMethod;
|
import org.jclouds.http.HttpMethod;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
|
import org.jclouds.http.functions.ReturnFalseOn404;
|
||||||
|
import org.jclouds.http.functions.ReturnTrueIf2xx;
|
||||||
import org.jclouds.rackspace.Authentication;
|
import org.jclouds.rackspace.Authentication;
|
||||||
import org.jclouds.rackspace.cloudservers.functions.ParseFlavorFromGsonResponse;
|
import org.jclouds.rackspace.cloudservers.functions.ParseFlavorFromGsonResponse;
|
||||||
import org.jclouds.rackspace.cloudservers.functions.ParseFlavorListFromGsonResponse;
|
import org.jclouds.rackspace.cloudservers.functions.ParseFlavorListFromGsonResponse;
|
||||||
|
@ -44,11 +53,18 @@ import org.jclouds.rackspace.cloudservers.functions.ParseImageFromGsonResponse;
|
||||||
import org.jclouds.rackspace.cloudservers.functions.ParseImageListFromGsonResponse;
|
import org.jclouds.rackspace.cloudservers.functions.ParseImageListFromGsonResponse;
|
||||||
import org.jclouds.rackspace.cloudservers.functions.ParseServerFromGsonResponse;
|
import org.jclouds.rackspace.cloudservers.functions.ParseServerFromGsonResponse;
|
||||||
import org.jclouds.rackspace.cloudservers.functions.ParseServerListFromGsonResponse;
|
import org.jclouds.rackspace.cloudservers.functions.ParseServerListFromGsonResponse;
|
||||||
|
import org.jclouds.rackspace.cloudservers.functions.ReturnFlavorNotFoundOn404;
|
||||||
|
import org.jclouds.rackspace.cloudservers.functions.ReturnImageNotFoundOn404;
|
||||||
|
import org.jclouds.rackspace.cloudservers.functions.ReturnServerNotFoundOn404;
|
||||||
|
import org.jclouds.rackspace.cloudservers.options.CreateServerOptions;
|
||||||
|
import org.jclouds.rackspace.cloudservers.options.ListOptions;
|
||||||
import org.jclouds.rest.JaxrsAnnotationProcessor;
|
import org.jclouds.rest.JaxrsAnnotationProcessor;
|
||||||
import org.jclouds.rest.config.JaxrsModule;
|
import org.jclouds.rest.config.JaxrsModule;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
@ -63,174 +79,368 @@ public class CloudServersConnectionTest {
|
||||||
|
|
||||||
JaxrsAnnotationProcessor.Factory factory;
|
JaxrsAnnotationProcessor.Factory factory;
|
||||||
|
|
||||||
|
private static final Class<? extends ListOptions[]> listOptionsVarargsClass = new ListOptions[] {}
|
||||||
|
.getClass();
|
||||||
|
|
||||||
|
private static final Class<? extends CreateServerOptions[]> createServerOptionsVarargsClass = new CreateServerOptions[] {}
|
||||||
|
.getClass();
|
||||||
|
|
||||||
public void testCreateServer() throws SecurityException, NoSuchMethodException {
|
public void testCreateServer() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("createServer", String.class,
|
Method method = CloudServersConnection.class.getMethod("createServer", String.class,
|
||||||
int.class, int.class);
|
int.class, int.class, createServerOptionsVarargsClass);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { "ralphie",
|
||||||
method, new Object[] { "ralphie", 2, 1 });
|
2, 1 });
|
||||||
|
assertEquals("{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1}}", httpMethod
|
||||||
|
.getEntity());
|
||||||
|
validateCreateServer(method, httpMethod);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateServerWithFile() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class.getMethod("createServer", String.class,
|
||||||
|
int.class, int.class, createServerOptionsVarargsClass);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { "ralphie",
|
||||||
|
2, 1, new CreateServerOptions[] { withFile("/etc/jclouds", "foo".getBytes()) } });
|
||||||
|
assertEquals(
|
||||||
|
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"personality\":[{\"path\":\"/etc/jclouds\",\"contents\":\"Zm9v\"}]}}",
|
||||||
|
httpMethod.getEntity());
|
||||||
|
validateCreateServer(method, httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateServerWithMetadata() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class.getMethod("createServer", String.class,
|
||||||
|
int.class, int.class, createServerOptionsVarargsClass);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { "ralphie",
|
||||||
|
2, 1, withMetadata(ImmutableMap.of("foo", "bar")) });
|
||||||
|
assertEquals(
|
||||||
|
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"metadata\":{\"foo\":\"bar\"}}}",
|
||||||
|
httpMethod.getEntity());
|
||||||
|
validateCreateServer(method, httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateServerWithIpGroup() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class.getMethod("createServer", String.class,
|
||||||
|
int.class, int.class, createServerOptionsVarargsClass);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { "ralphie",
|
||||||
|
2, 1, withSharedIpGroup(2) });
|
||||||
|
assertEquals(
|
||||||
|
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"sharedIpGroupId\":2}}",
|
||||||
|
httpMethod.getEntity());
|
||||||
|
validateCreateServer(method, httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCreateServerWithIpGroupAndSharedIp() throws SecurityException,
|
||||||
|
NoSuchMethodException, UnknownHostException {
|
||||||
|
Method method = CloudServersConnection.class.getMethod("createServer", String.class,
|
||||||
|
int.class, int.class, createServerOptionsVarargsClass);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] {
|
||||||
|
"ralphie",
|
||||||
|
2,
|
||||||
|
1,
|
||||||
|
withSharedIpGroup(2).withSharedIp(
|
||||||
|
InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 })) });
|
||||||
|
assertEquals(
|
||||||
|
"{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1,\"sharedIpGroupId\":2,\"addresses\":{\"public\":[\"127.0.0.1\"]}}}",
|
||||||
|
httpMethod.getEntity());
|
||||||
|
validateCreateServer(method, httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateCreateServer(Method method, HttpRequest httpMethod) {
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/servers");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/servers");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
|
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
|
||||||
assertEquals("{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1}}", httpMethod
|
|
||||||
.getEntity());
|
|
||||||
assertEquals(httpMethod.getHeaders().size(), 2);
|
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
.singletonList(httpMethod.getEntity().toString().getBytes().length + ""));
|
.singletonList(httpMethod.getEntity().toString().getBytes().length + ""));
|
||||||
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||||
.singletonList(MediaType.APPLICATION_JSON));
|
.singletonList(MediaType.APPLICATION_JSON));
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseServerFromGsonResponse.class);
|
ParseServerFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
|
assertNotNull(processor.getPostEntityBinderOrNull(method, new Object[] { "", 1, 2,
|
||||||
|
new CreateServerOptions[] { CreateServerOptions.Builder.withSharedIpGroup(1) } }));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListServers() throws SecurityException, NoSuchMethodException {
|
public void testListServers() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("listServers");
|
Method method = CloudServersConnection.class
|
||||||
|
.getMethod("listServers", listOptionsVarargsClass);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] {});
|
||||||
method, new Object[] {});
|
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/servers");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/servers");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseServerListFromGsonResponse.class);
|
ParseServerListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime now = new DateTime();
|
||||||
|
|
||||||
|
public void testListServersOptions() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class
|
||||||
|
.getMethod("listServers", listOptionsVarargsClass);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method,
|
||||||
|
new Object[] { changesSince(now).maxResults(1).startAt(2) });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/servers");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json" + "&limit=1&changes-since="
|
||||||
|
+ now.getMillis() / 1000 + "&offset=2");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
|
ParseServerListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListServersDetail() throws SecurityException, NoSuchMethodException {
|
public void testListServersDetail() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("listServerDetails");
|
Method method = CloudServersConnection.class
|
||||||
|
.getMethod("listServers", listOptionsVarargsClass);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method,
|
||||||
method, new Object[] {});
|
new Object[] { withDetails() });
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/detail");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/detail");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseServerListFromGsonResponse.class);
|
ParseServerListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListFlavors() throws SecurityException, NoSuchMethodException {
|
public void testListFlavors() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("listFlavors");
|
Method method = CloudServersConnection.class
|
||||||
|
.getMethod("listFlavors", listOptionsVarargsClass);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] {});
|
||||||
method, new Object[] {});
|
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/flavors");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/flavors");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseFlavorListFromGsonResponse.class);
|
ParseFlavorListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListFlavorsOptions() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class
|
||||||
|
.getMethod("listFlavors", listOptionsVarargsClass);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method,
|
||||||
|
new Object[] { changesSince(now).maxResults(1).startAt(2) });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/flavors");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json" + "&limit=1&changes-since="
|
||||||
|
+ now.getMillis() / 1000 + "&offset=2");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
|
ParseFlavorListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListFlavorsDetail() throws SecurityException, NoSuchMethodException {
|
public void testListFlavorsDetail() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("listFlavorDetails");
|
Method method = CloudServersConnection.class
|
||||||
|
.getMethod("listFlavors", listOptionsVarargsClass);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method,
|
||||||
method, new Object[] {});
|
new Object[] { withDetails() });
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/flavors/detail");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/flavors/detail");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseFlavorListFromGsonResponse.class);
|
ParseFlavorListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListImages() throws SecurityException, NoSuchMethodException {
|
public void testListImages() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("listImages");
|
Method method = CloudServersConnection.class.getMethod("listImages", listOptionsVarargsClass);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] {});
|
||||||
method, new Object[] {});
|
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/images");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/images");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseImageListFromGsonResponse.class);
|
ParseImageListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListImagesDetail() throws SecurityException, NoSuchMethodException {
|
public void testListImagesDetail() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("listImageDetails");
|
Method method = CloudServersConnection.class.getMethod("listImages", listOptionsVarargsClass);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method,
|
||||||
method, new Object[] {});
|
new Object[] { withDetails() });
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/images/detail");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/images/detail");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseImageListFromGsonResponse.class);
|
ParseImageListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetImageDetails() throws SecurityException, NoSuchMethodException {
|
public void testListFlavorsDetailOptions() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("getImageDetails", int.class);
|
Method method = CloudServersConnection.class
|
||||||
|
.getMethod("listFlavors", listOptionsVarargsClass);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method,
|
||||||
method, new Object[] { 2 });
|
new Object[] { withDetails().changesSince(now).maxResults(1).startAt(2) });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/flavors/detail");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json" + "&limit=1&changes-since="
|
||||||
|
+ now.getMillis() / 1000 + "&offset=2");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
|
ParseFlavorListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListImagesOptions() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class.getMethod("listImages", listOptionsVarargsClass);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method,
|
||||||
|
new Object[] { changesSince(now).maxResults(1).startAt(2) });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/images");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json" + "&limit=1&changes-since="
|
||||||
|
+ now.getMillis() / 1000 + "&offset=2");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
|
ParseImageListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListImagesDetailOptions() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class.getMethod("listImages", listOptionsVarargsClass);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method,
|
||||||
|
new Object[] { withDetails().changesSince(now).maxResults(1).startAt(2) });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/images/detail");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json" + "&limit=1&changes-since="
|
||||||
|
+ now.getMillis() / 1000 + "&offset=2");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
|
ParseImageListFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetImage() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class.getMethod("getImage", int.class);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2 });
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/images/2");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/images/2");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseImageFromGsonResponse.class);
|
ParseImageFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
|
||||||
|
ReturnImageNotFoundOn404.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetFlavorDetails() throws SecurityException, NoSuchMethodException {
|
public void testGetFlavor() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("getFlavorDetails", int.class);
|
Method method = CloudServersConnection.class.getMethod("getFlavor", int.class);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2 });
|
||||||
method, new Object[] { 2 });
|
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/flavors/2");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/flavors/2");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseFlavorFromGsonResponse.class);
|
ParseFlavorFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
|
||||||
|
ReturnFlavorNotFoundOn404.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetServerDetails() throws SecurityException, NoSuchMethodException {
|
public void testGetServer() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("getServerDetails", int.class);
|
Method method = CloudServersConnection.class.getMethod("getServer", int.class);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2 });
|
||||||
method, new Object[] { 2 });
|
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2");
|
||||||
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
assertEquals(httpMethod.getMethod(), HttpMethod.GET);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
assertEquals(JaxrsAnnotationProcessor.getParserOrThrowException(method),
|
assertEquals(processor.createResponseParser(method).getClass(),
|
||||||
ParseServerFromGsonResponse.class);
|
ParseServerFromGsonResponse.class);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
|
||||||
|
ReturnServerNotFoundOn404.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeleteServer() throws SecurityException, NoSuchMethodException {
|
public void testDeleteServer() throws SecurityException, NoSuchMethodException {
|
||||||
Method method = CloudServersConnection.class.getMethod("deleteServer", int.class);
|
Method method = CloudServersConnection.class.getMethod("deleteServer", int.class);
|
||||||
URI endpoint = URI.create("http://localhost");
|
URI endpoint = URI.create("http://localhost");
|
||||||
HttpRequest httpMethod = factory.create(CloudServersConnection.class).createRequest(endpoint,
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2 });
|
||||||
method, new Object[] { 2 });
|
|
||||||
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2");
|
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2");
|
||||||
assertEquals(httpMethod.getMethod(), HttpMethod.DELETE);
|
assertEquals(httpMethod.getMethod(), HttpMethod.DELETE);
|
||||||
assertEquals(httpMethod.getHeaders().size(), 0);
|
assertEquals(httpMethod.getHeaders().size(), 0);
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
|
||||||
|
ReturnFalseOn404.class);
|
||||||
|
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testChangeAdminPass() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class.getMethod("changeAdminPass", int.class,
|
||||||
|
String.class);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2, "foo" });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
|
.singletonList(httpMethod.getEntity().toString().getBytes().length + ""));
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||||
|
.singletonList(MediaType.APPLICATION_JSON));
|
||||||
|
assertEquals("{\"server\":{\"adminPass\":\"foo\"}}", httpMethod.getEntity());
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
|
||||||
|
ReturnFalseOn404.class);
|
||||||
|
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testChangeServerName() throws SecurityException, NoSuchMethodException {
|
||||||
|
Method method = CloudServersConnection.class.getMethod("renameServer", int.class,
|
||||||
|
String.class);
|
||||||
|
URI endpoint = URI.create("http://localhost");
|
||||||
|
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2, "foo" });
|
||||||
|
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
|
||||||
|
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2");
|
||||||
|
assertEquals(httpMethod.getMethod(), HttpMethod.PUT);
|
||||||
|
assertEquals(httpMethod.getHeaders().size(), 2);
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_LENGTH), Collections
|
||||||
|
.singletonList(httpMethod.getEntity().toString().getBytes().length + ""));
|
||||||
|
assertEquals(httpMethod.getHeaders().get(HttpHeaders.CONTENT_TYPE), Collections
|
||||||
|
.singletonList(MediaType.APPLICATION_JSON));
|
||||||
|
assertEquals("{\"server\":{\"name\":\"foo\"}}", httpMethod.getEntity());
|
||||||
|
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
|
||||||
|
ReturnFalseOn404.class);
|
||||||
|
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
JaxrsAnnotationProcessor processor;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
void setupFactory() {
|
void setupFactory() {
|
||||||
factory = Guice.createInjector(new AbstractModule() {
|
factory = Guice.createInjector(new AbstractModule() {
|
||||||
|
@ -248,6 +458,7 @@ public class CloudServersConnectionTest {
|
||||||
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
}, new JaxrsModule(), new ExecutorServiceModule(new WithinThreadExecutorService()),
|
||||||
new JavaUrlHttpCommandExecutorServiceModule()).getInstance(
|
new JavaUrlHttpCommandExecutorServiceModule()).getInstance(
|
||||||
JaxrsAnnotationProcessor.Factory.class);
|
JaxrsAnnotationProcessor.Factory.class);
|
||||||
|
processor = factory.create(CloudServersConnection.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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
|
||||||
|
*
|
||||||
|
* 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.rackspace.cloudservers.binders;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpMethod;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.functions.config.ParserModule;
|
||||||
|
import org.jclouds.rackspace.cloudservers.binders.ChangeAdminPassBinder;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code ChangeAdminPassBinder}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "cloudservers.ChangeAdminPassBinderTest")
|
||||||
|
public class ChangeAdminPassBinderTest {
|
||||||
|
|
||||||
|
Injector injector = Guice.createInjector(new ParserModule());
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
|
public void testPostIsIncorrect() {
|
||||||
|
ChangeAdminPassBinder binder = new ChangeAdminPassBinder();
|
||||||
|
injector.injectMembers(binder);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
|
||||||
|
binder.addEntityToRequest(ImmutableMap.of("adminPass", "foo"), request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void testMustBeString() {
|
||||||
|
ChangeAdminPassBinder binder = new ChangeAdminPassBinder();
|
||||||
|
injector.injectMembers(binder);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
|
||||||
|
binder.addEntityToRequest(new File("foo"), request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCorrect() {
|
||||||
|
ChangeAdminPassBinder binder = new ChangeAdminPassBinder();
|
||||||
|
injector.injectMembers(binder);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("/"));
|
||||||
|
binder.addEntityToRequest("foo", request);
|
||||||
|
assertEquals("{\"server\":{\"adminPass\":\"foo\"}}", request.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })
|
||||||
|
public void testNullIsBad() {
|
||||||
|
ChangeAdminPassBinder binder = new ChangeAdminPassBinder();
|
||||||
|
injector.injectMembers(binder);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("/"));
|
||||||
|
binder.addEntityToRequest(null, request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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
|
||||||
|
*
|
||||||
|
* 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.rackspace.cloudservers.binders;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpMethod;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.functions.config.ParserModule;
|
||||||
|
import org.jclouds.rackspace.cloudservers.binders.ChangeServerNameBinder;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code ChangeServerNameBinder}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "cloudservers.ChangeServerNameBinderTest")
|
||||||
|
public class ChangeServerNameBinderTest {
|
||||||
|
|
||||||
|
Injector injector = Guice.createInjector(new ParserModule());
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
|
public void testPostIsIncorrect() {
|
||||||
|
ChangeServerNameBinder binder = new ChangeServerNameBinder();
|
||||||
|
injector.injectMembers(binder);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
|
||||||
|
binder.addEntityToRequest(ImmutableMap.of("name", "foo"), request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void testMustBeString() {
|
||||||
|
ChangeServerNameBinder binder = new ChangeServerNameBinder();
|
||||||
|
injector.injectMembers(binder);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
|
||||||
|
binder.addEntityToRequest(new File("foo"), request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCorrect() {
|
||||||
|
ChangeServerNameBinder binder = new ChangeServerNameBinder();
|
||||||
|
injector.injectMembers(binder);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("/"));
|
||||||
|
binder.addEntityToRequest("foo", request);
|
||||||
|
assertEquals("{\"server\":{\"name\":\"foo\"}}", request.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })
|
||||||
|
public void testNullIsBad() {
|
||||||
|
ChangeServerNameBinder binder = new ChangeServerNameBinder();
|
||||||
|
injector.injectMembers(binder);
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("/"));
|
||||||
|
binder.addEntityToRequest(null, request);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package org.jclouds.rackspace.cloudservers.options;
|
||||||
|
|
||||||
|
import static org.jclouds.rackspace.cloudservers.options.ListOptions.Builder.*;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code ListOptions}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "rackspace.ListOptionsTest")
|
||||||
|
public class ListOptionsTest {
|
||||||
|
|
||||||
|
public void testWithDetails() {
|
||||||
|
ListOptions options = new ListOptions().withDetails();
|
||||||
|
assertEquals(options.buildPathSuffix(), "/detail");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWithDetailsStatic() {
|
||||||
|
ListOptions options = withDetails();
|
||||||
|
assertEquals(options.buildPathSuffix(), "/detail");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testChangesSince() {
|
||||||
|
DateTime ifModifiedSince = new DateTime();
|
||||||
|
ListOptions options = new ListOptions().changesSince(ifModifiedSince);
|
||||||
|
assertEquals(ImmutableList.of(ifModifiedSince.getMillis() / 1000 + ""), options
|
||||||
|
.buildQueryParameters().get("changes-since"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testStartAt() {
|
||||||
|
long offset = 1;
|
||||||
|
ListOptions options = new ListOptions().startAt(offset);
|
||||||
|
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMaxResults() {
|
||||||
|
int limit = 1;
|
||||||
|
ListOptions options = new ListOptions().maxResults(limit);
|
||||||
|
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testChangesSinceStatic() {
|
||||||
|
DateTime ifModifiedSince = new DateTime();
|
||||||
|
ListOptions options = changesSince(ifModifiedSince);
|
||||||
|
assertEquals(ImmutableList.of(ifModifiedSince.getMillis() / 1000 + ""), options
|
||||||
|
.buildQueryParameters().get("changes-since"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testStartAtStatic() {
|
||||||
|
long offset = 1;
|
||||||
|
ListOptions options = startAt(offset);
|
||||||
|
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMaxResultsStatic() {
|
||||||
|
int limit = 1;
|
||||||
|
ListOptions options = maxResults(limit);
|
||||||
|
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,6 @@ import org.jclouds.rest.ResponseParser;
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
|
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
|
||||||
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
package org.jclouds.rackspace.options;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
|
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options used to control paginated results (aka list commands).
|
||||||
|
*
|
||||||
|
* @see <a href="http://docs.rackspacecloud.com/servers/api/cs-devguide-latest.pdf" />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class BaseListOptions extends BaseHttpRequestOptions {
|
||||||
|
public static final BaseListOptions NONE = new BaseListOptions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only return objects changed since this time.
|
||||||
|
*/
|
||||||
|
public BaseListOptions changesSince(DateTime ifModifiedSince) {
|
||||||
|
this.queryParameters.put("changes-since", checkNotNull(ifModifiedSince, "ifModifiedSince")
|
||||||
|
.getMillis()
|
||||||
|
/ 1000 + "");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates where to begin listing. The list will only include objects that occur after the
|
||||||
|
* offset. This is convenient for pagination: To get the next page of results use the last result
|
||||||
|
* number of the current page + current page offset as the offset.
|
||||||
|
*/
|
||||||
|
public BaseListOptions startAt(long offset) {
|
||||||
|
checkState(offset >= 0, "offset must be >= 0");
|
||||||
|
queryParameters.put("offset", Long.toString(checkNotNull(offset, "offset")));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To reduce load on the service, list operations will return a maximum of 1,000 items at a time.
|
||||||
|
* To navigate the collection, the parameters limit and offset can be set in the URI
|
||||||
|
* (e.g.?limit=0&offset=0). If an offset is given beyond the end of a list an empty list will be
|
||||||
|
* returned.
|
||||||
|
* <p/>
|
||||||
|
* Note that list operations never return itemNotFound (404) faults.
|
||||||
|
*/
|
||||||
|
public BaseListOptions maxResults(int limit) {
|
||||||
|
checkState(limit >= 0, "limit must be >= 0");
|
||||||
|
checkState(limit <= 10000, "limit must be <= 10000");
|
||||||
|
queryParameters.put("limit", Integer.toString(limit));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BaseListOptions#startAt(long)
|
||||||
|
*/
|
||||||
|
public static BaseListOptions startAt(long prefix) {
|
||||||
|
BaseListOptions options = new BaseListOptions();
|
||||||
|
return options.startAt(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BaseListOptions#maxResults(long)
|
||||||
|
*/
|
||||||
|
public static BaseListOptions maxResults(int maxKeys) {
|
||||||
|
BaseListOptions options = new BaseListOptions();
|
||||||
|
return options.maxResults(maxKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see BaseListOptions#changesSince(DateTime)
|
||||||
|
*/
|
||||||
|
public static BaseListOptions changesSince(DateTime since) {
|
||||||
|
BaseListOptions options = new BaseListOptions();
|
||||||
|
return options.changesSince(since);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package org.jclouds.rackspace.options;
|
||||||
|
|
||||||
|
import static org.jclouds.rackspace.options.BaseListOptions.Builder.changesSince;
|
||||||
|
import static org.jclouds.rackspace.options.BaseListOptions.Builder.maxResults;
|
||||||
|
import static org.jclouds.rackspace.options.BaseListOptions.Builder.startAt;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code ListOptions}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "rackspace.ListOptionsTest")
|
||||||
|
public class BaseListOptionsTest {
|
||||||
|
|
||||||
|
public void testChangesSince() {
|
||||||
|
DateTime ifModifiedSince = new DateTime();
|
||||||
|
BaseListOptions options = new BaseListOptions().changesSince(ifModifiedSince);
|
||||||
|
assertEquals(ImmutableList.of(ifModifiedSince.getMillis() / 1000 + ""), options
|
||||||
|
.buildQueryParameters().get("changes-since"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testStartAt() {
|
||||||
|
long offset = 1;
|
||||||
|
BaseListOptions options = new BaseListOptions().startAt(offset);
|
||||||
|
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMaxResults() {
|
||||||
|
int limit = 1;
|
||||||
|
BaseListOptions options = new BaseListOptions().maxResults(limit);
|
||||||
|
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testChangesSinceStatic() {
|
||||||
|
DateTime ifModifiedSince = new DateTime();
|
||||||
|
BaseListOptions options = changesSince(ifModifiedSince);
|
||||||
|
assertEquals(ImmutableList.of(ifModifiedSince.getMillis() / 1000 + ""), options
|
||||||
|
.buildQueryParameters().get("changes-since"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testStartAtStatic() {
|
||||||
|
long offset = 1;
|
||||||
|
BaseListOptions options = startAt(offset);
|
||||||
|
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("offset"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMaxResultsStatic() {
|
||||||
|
int limit = 1;
|
||||||
|
BaseListOptions options = maxResults(limit);
|
||||||
|
assertEquals(ImmutableList.of("1"), options.buildQueryParameters().get("limit"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue