refactored create server command to have less args

This commit is contained in:
Adrian Cole 2012-01-29 19:41:22 -08:00
parent ac2c2e75e8
commit e7961c64cc
6 changed files with 371 additions and 103 deletions

View File

@ -0,0 +1,192 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.glesys.domain;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Objects;
/**
*
*
* @author Adrian Cole
*/
public class ServerSpec {
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return Builder.fromServerSpecification(this);
}
public static class Builder {
protected String datacenter;
protected String platform;
protected String templateName;
protected int diskSizeGB;
protected int memorySizeMB;
protected int cpuCores;
protected int transfer;
public Builder datacenter(String datacenter) {
this.datacenter = datacenter;
return this;
}
public Builder platform(String platform) {
this.platform = platform;
return this;
}
public Builder templateName(String templateName) {
this.templateName = templateName;
return this;
}
public Builder diskSizeGB(int diskSizeGB) {
this.diskSizeGB = diskSizeGB;
return this;
}
public Builder memorySizeMB(int memorySizeMB) {
this.memorySizeMB = memorySizeMB;
return this;
}
public Builder cpuCores(int cpuCores) {
this.cpuCores = cpuCores;
return this;
}
public Builder transfer(int transfer) {
this.transfer = transfer;
return this;
}
public ServerSpec build() {
return new ServerSpec(platform, datacenter, memorySizeMB, diskSizeGB, templateName, cpuCores, transfer);
}
public static Builder fromServerSpecification(ServerSpec in) {
return new Builder().platform(in.getPlatform()).datacenter(in.getDatacenter())
.memorySizeMB(in.getMemorySizeMB()).diskSizeGB(in.getDiskSizeGB()).templateName(in.getTemplateName())
.cpuCores(in.getCpuCores()).transfer(in.getTransfer());
}
}
protected final String platform;
protected final String datacenter;
protected final int memorySizeMB;
protected final int diskSizeGB;
protected final String templateName;
protected final int cpuCores;
protected final int transfer;
protected ServerSpec(String platform, String datacenter, int memorySizeMB, int diskSizeGB, String templateName,
int cpuCores, int transfer) {
this.platform = checkNotNull(platform, "platform");
this.datacenter = checkNotNull(datacenter, "datacenter");
this.memorySizeMB = memorySizeMB;
this.diskSizeGB = diskSizeGB;
this.templateName = checkNotNull(templateName, "templateName");
this.cpuCores = cpuCores;
this.transfer = transfer;
}
/**
* @return the data center to create the new server in
*/
public String getDatacenter() {
return datacenter;
}
/**
* @return the platform to use (i.e. "Xen" or "OpenVZ")
*/
public String getPlatform() {
return platform;
}
/**
* @return the os template to use to create the new server
*/
public String getTemplateName() {
return templateName;
}
/**
* @return the amount of disk space, in GB, to allocate
*/
public int getDiskSizeGB() {
return diskSizeGB;
}
/**
* @return the memory, in MB, to allocate
*/
public int getMemorySizeMB() {
return memorySizeMB;
}
/**
* @return the number of CPU cores to allocate
*/
public int getCpuCores() {
return cpuCores;
}
/**
* @return number of transfer
*/
public int getTransfer() {
return transfer;
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (object instanceof ServerSpec) {
final ServerSpec that = ServerSpec.class.cast(object);
return equal(platform, that.platform) && equal(datacenter, that.datacenter)
&& equal(memorySizeMB, that.memorySizeMB) && equal(diskSizeGB, that.diskSizeGB)
&& equal(templateName, that.templateName) && equal(cpuCores, that.cpuCores)
&& equal(transfer, that.transfer);
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hashCode(platform, datacenter, memorySizeMB, diskSizeGB, templateName, cpuCores, transfer);
}
@Override
public String toString() {
return toStringHelper("").add("platform", platform).add("datacenter", datacenter)
.add("templateName", templateName).add("cpuCores", cpuCores).add("cpuCores", cpuCores)
.add("diskSizeGB", diskSizeGB).add("transfer", transfer).toString();
}
}

View File

@ -29,11 +29,12 @@ import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import org.jclouds.glesys.domain.AllowedArgumentsForCreateServer;
import org.jclouds.glesys.domain.Console;
import org.jclouds.glesys.domain.Server;
import org.jclouds.glesys.domain.AllowedArgumentsForCreateServer;
import org.jclouds.glesys.domain.ServerDetails;
import org.jclouds.glesys.domain.ServerLimit;
import org.jclouds.glesys.domain.ServerSpec;
import org.jclouds.glesys.domain.ServerStatus;
import org.jclouds.glesys.domain.Template;
import org.jclouds.glesys.functions.ParseTemplatesFromHttpResponse;
@ -45,6 +46,8 @@ import org.jclouds.glesys.options.ServerStatusOptions;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.MapBinder;
import org.jclouds.rest.annotations.PayloadParam;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.rest.annotations.SelectJson;
@ -56,7 +59,7 @@ import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Server via their REST API.
* <p/>
*
*
* @author Adrian Cole
* @author Adam Lowe
* @see ServerClient
@ -105,7 +108,6 @@ public interface ServerAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<SortedMap<String, ServerLimit>> getServerLimits(@FormParam("serverid") String id);
/**
* @see ServerClient#getConsole
*/
@ -116,7 +118,6 @@ public interface ServerAsyncClient {
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Console> getConsole(@FormParam("serverid") String id);
/**
* @see ServerClient#getAllowedArgumentsForCreateServerByPlatform
*/
@ -125,7 +126,7 @@ public interface ServerAsyncClient {
@SelectJson("argumentslist")
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Map<String, AllowedArgumentsForCreateServer>> getAllowedArgumentsForCreateServerByPlatform();
/**
* @see ServerClient#getTemplates
*/
@ -134,14 +135,15 @@ public interface ServerAsyncClient {
@ResponseParser(ParseTemplatesFromHttpResponse.class)
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Set<Template>> getTemplates();
/**
* @see ServerClient#stopServer
*/
@POST
@Path("/server/resetlimit/format/json")
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<SortedMap<String, ServerLimit>> resetServerLimit(@FormParam("serverid") String id, @FormParam("type") String type);
ListenableFuture<SortedMap<String, ServerLimit>> resetServerLimit(@FormParam("serverid") String id,
@FormParam("type") String type);
/**
* @see ServerClient#rebootServer
@ -181,22 +183,16 @@ public interface ServerAsyncClient {
ListenableFuture<ServerDetails> hardStopServer(@FormParam("serverid") String id);
/**
* @see ServerClient#createServer
* @see ServerClient#createServerWithHostnameAndRootPassword
*/
@POST
@SelectJson("server")
@Path("/server/create/format/json")
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<ServerDetails> createServer(@FormParam("datacenter") String datacenter,
@FormParam("platform") String platform,
@FormParam("hostname") String hostname,
@FormParam("templatename") String templateName,
@FormParam("disksize") int diskSize,
@FormParam("memorysize") int memorySize,
@FormParam("cpucores") int cpuCores,
@FormParam("rootpassword") String rootPassword,
@FormParam("transfer") int transfer,
CreateServerOptions... options);
@MapBinder(CreateServerOptions.class)
ListenableFuture<ServerDetails> createServerWithHostnameAndRootPassword(ServerSpec serverSpec,
@PayloadParam("hostname") String hostname, @PayloadParam("rootpassword") String rootPassword,
CreateServerOptions... options);
/**
* @see ServerClient#cloneServer
@ -206,8 +202,7 @@ public interface ServerAsyncClient {
@SelectJson("server")
@Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<ServerDetails> cloneServer(@FormParam("serverid") String serverid,
@FormParam("hostname") String hostname,
CloneServerOptions... options);
@FormParam("hostname") String hostname, CloneServerOptions... options);
/**
* @see ServerClient#editServer
@ -237,6 +232,7 @@ public interface ServerAsyncClient {
*/
@POST
@Path("/server/resourceusage/format/json")
void resourceUsage(@FormParam("serverid") String id, @FormParam("resource") String resource, @FormParam("resolution") String resolution);
void resourceUsage(@FormParam("serverid") String id, @FormParam("resource") String resource,
@FormParam("resolution") String resolution);
}

View File

@ -28,6 +28,7 @@ import org.jclouds.glesys.domain.Console;
import org.jclouds.glesys.domain.Server;
import org.jclouds.glesys.domain.ServerDetails;
import org.jclouds.glesys.domain.ServerLimit;
import org.jclouds.glesys.domain.ServerSpec;
import org.jclouds.glesys.domain.ServerStatus;
import org.jclouds.glesys.domain.Template;
import org.jclouds.glesys.options.CloneServerOptions;
@ -41,7 +42,7 @@ import com.google.common.annotations.Beta;
/**
* Provides synchronous access to Server.
* <p/>
*
*
* @author Adrian Cole
* @author Adam Lowe
* @see ServerAsyncClient
@ -52,7 +53,7 @@ public interface ServerClient {
/**
* Get a list of all servers on this account.
*
*
* @return an account's associated server objects.
*/
Set<Server> listServers();
@ -61,18 +62,21 @@ public interface ServerClient {
* Get detailed information about a server such as hostname, hardware
* configuration (cpu, memory and disk), ip addresses, cost, transfer, os and
* more.
*
* @param id id of the server
*
* @param id
* id of the server
* @return server or null if not found
*/
ServerDetails getServerDetails(String id);
/**
* Get detailed information about a server status including up-time and hardware usage
* (cpu, disk, memory and bandwidth)
*
* @param id id of the server
* @param options optional parameters
* Get detailed information about a server status including up-time and
* hardware usage (cpu, disk, memory and bandwidth)
*
* @param id
* id of the server
* @param options
* optional parameters
* @return the status of the server or null if not found
*/
ServerStatus getServerStatus(String id, ServerStatusOptions... options);
@ -80,130 +84,141 @@ public interface ServerClient {
/**
* Get detailed information about a server's limits (for OpenVZ only).
* <p/>
*
* @param id id of the server
*
* @param id
* id of the server
* @return the requested information about the server or null if not found
*/
Map<String, ServerLimit> getServerLimits(String id);
/**
* Get information about how to connect to a server via VNC
*
* @param id id of the server
*
* @param id
* id of the server
* @return the requested information about the server or null if not found
*/
Console getConsole(String id);
/**
* Get information about the OS templates available
*
*
* @return the set of information about each template
*/
Set<Template> getTemplates();
/**
* Get information about valid arguments to #createServer for each platform
*
*
* @return a map of argument lists, keyed on platform
*/
Map<String, AllowedArgumentsForCreateServer> getAllowedArgumentsForCreateServerByPlatform();
/**
* Reset the fail count for a server limit (for OpenVZ only).
*
* @param id id of the server
* @param type the type of limit to reset
*
* @param id
* id of the server
* @param type
* the type of limit to reset
*/
Map<String, ServerLimit> resetServerLimit(String id, String type);
/**
* Reboot a server
*
* @param id id of the server
*
* @param id
* id of the server
*/
ServerDetails rebootServer(String id);
/**
* Start a server
*
* @param id id of the server
*
* @param id
* id of the server
*/
ServerDetails startServer(String id);
/**
* Stop a server
*
* @param id id of the server
*
* @param id
* id of the server
*/
void stopServer(String id);
/**
* hard stop a server
*
* @param id id of the server
*
* @param id
* id of the server
*/
void hardStopServer(String id);
/**
* Create a new server
*
* @param datacenter the data center to create the new server in
* @param platform the platform to use (i.e. "Xen" or "OpenVZ")
* @param hostname the host name of the new server
* @param templateName the template to use to create the new server
* @param diskSize the amount of disk space, in GB, to allocate
* @param memorySize the memory, in MB, to allocate
* @param cpuCores the number of CPU cores to allocate
* @param rootPassword the root password to use
* @param transfer the transfer size
* @param options optional settings ex. description
*
* @param hostname
* the host name of the new server
* @param rootPassword
* the root password to use
* @param options
* optional settings ex. description
*/
//TODO: make a ServerSpecification object like LaunchSpecification in ec2 as there are too many args
@Beta
ServerDetails createServer(String datacenter,String platform,String hostname,
String templateName, int diskSize, int memorySize, int cpuCores,
String rootPassword, int transfer, CreateServerOptions... options);
ServerDetails createServerWithHostnameAndRootPassword(ServerSpec serverSpec, String hostname, String rootPassword,
CreateServerOptions... options);
/**
* Edit the configuration of a server
*
* @param serverid the serverId of the server to edit
* @param options the settings to change
*
* @param serverid
* the serverId of the server to edit
* @param options
* the settings to change
*/
ServerDetails editServer(String serverid, EditServerOptions... options);
/**
* Clone a server
*
* @param serverid the serverId of the server to clone
* @param hostname the new host name of the cloned server
* @param options the settings to change
*
* @param serverid
* the serverId of the server to clone
* @param hostname
* the new host name of the cloned server
* @param options
* the settings to change
*/
ServerDetails cloneServer(String serverid, String hostname, CloneServerOptions... options);
/**
* Destroy a server
*
* @param id the id of the server
* @param keepIp if DestroyServerOptions.keepIp(true) the servers ip will be retained for use in your GleSYS account
*
* @param id
* the id of the server
* @param keepIp
* if DestroyServerOptions.keepIp(true) the servers ip will be
* retained for use in your GleSYS account
*/
ServerDetails destroyServer(String id, DestroyServerOptions keepIp);
/**
* Reset the root password of a server
*
* @param id the id of the server
* @param password the new password to use
*
* @param id
* the id of the server
* @param password
* the new password to use
*/
void resetPassword(String id, String password);
/**
* Return resource usage over time for server
*
* @param id the id of the server
* @param resource the name of the resource to retrieve usage information for
*
* @param id
* the id of the server
* @param resource
* the name of the resource to retrieve usage information for
*/
@Beta
// TODO: better name

View File

@ -18,12 +18,57 @@
*/
package org.jclouds.glesys.options;
import org.jclouds.http.options.BaseHttpRequestOptions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Predicates.instanceOf;
import static com.google.common.collect.Iterables.find;
import java.util.Map;
import org.jclouds.glesys.domain.ServerSpec;
import org.jclouds.http.HttpRequest;
import org.jclouds.io.payloads.UrlEncodedFormPayload;
import org.jclouds.rest.MapBinder;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimaps;
/**
* @author Adam Lowe
*/
public class CreateServerOptions extends BaseHttpRequestOptions {
public class CreateServerOptions implements MapBinder {
private String ip;
private String description;
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, String> postParams) {
checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest<?>,
"this binder is only valid for GeneratedHttpRequests!");
GeneratedHttpRequest<?> gRequest = (GeneratedHttpRequest<?>) request;
checkState(gRequest.getArgs() != null, "args should be initialized at this point");
ImmutableMultimap.Builder<String, String> formParams = ImmutableMultimap.<String, String> builder();
formParams.putAll(Multimaps.forMap(postParams));
ServerSpec serverSpec = ServerSpec.class.cast(find(gRequest.getArgs(), instanceOf(ServerSpec.class)));
formParams.put("datacenter", serverSpec.getDatacenter());
formParams.put("platform", serverSpec.getPlatform());
formParams.put("templatename", serverSpec.getTemplateName());
formParams.put("disksize", serverSpec.getDiskSizeGB() + "");
formParams.put("memorysize", serverSpec.getMemorySizeMB() + "");
formParams.put("cpucores", serverSpec.getCpuCores() + "");
formParams.put("transfer", serverSpec.getTransfer() + "");
if (ip != null)
formParams.put("ip", ip);
if (description != null)
formParams.put("description", description);
request.setPayload(new UrlEncodedFormPayload(formParams.build()));
return request;
}
public static class Builder {
/**
* @see CreateServerOptions#description
@ -43,19 +88,25 @@ public class CreateServerOptions extends BaseHttpRequestOptions {
}
/**
* @param description the description of the server
* @param description
* the description of the server
*/
public CreateServerOptions description(String description) {
formParameters.put("description", description);
this.description = description;
return this;
}
/**
* @param ip the ip address to assign to the server
* @param ip
* the ip address to assign to the server
*/
public CreateServerOptions ip(String ip) {
formParameters.put("ip", ip);
this.ip = ip;
return this;
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
throw new IllegalArgumentException();
}
}

View File

@ -183,22 +183,27 @@ public class ServerClientExpectTest extends BaseRestClientExpectTest<GleSYSClien
.put("Accept", "application/json")
.put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
.payload(newUrlEncodedFormPayload(ImmutableMultimap.<String, String>builder()
.put("cpucores", "1")
.put("memorysize", "512")
.put("datacenter", "Falkenberg")
.put("transfer", "50")
.put("rootpassword", "password")
.put("hostname", "jclouds-test")
.put("rootpassword", "password")
.put("datacenter", "Falkenberg")
.put("platform", "OpenVZ")
.put("templatename", "Ubuntu 32-bit")
.put("disksize", "5").build())).build(),
.put("disksize", "5")
.put("memorysize", "512")
.put("cpucores", "1")
.put("transfer", "50")
.build())).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/server_noip.json")).build()).getServerClient();
Cost cost = Cost.builder().amount(6.38).currency("EUR").timePeriod("month").build();
ServerDetails expected = ServerDetails.builder().id("vz1541880").hostname("mammamia").datacenter("Falkenberg").platform("OpenVZ")
.templateName("Ubuntu 11.04 64-bit").description("description").cpuCores(1).memorySize(128).diskSize(5).transfer(50).cost(cost).build();
assertEquals(client.createServer("Falkenberg", "OpenVZ", "jclouds-test", "Ubuntu 32-bit", 5, 512, 1, "password", 50).toString(), expected.toString());
assertEquals(
client.createServerWithHostnameAndRootPassword(
ServerSpec.builder().datacenter("Falkenberg").platform("OpenVZ").templateName("Ubuntu 32-bit")
.diskSizeGB(5).memorySizeMB(512).cpuCores(1).transfer(50).build(), "jclouds-test", "password").toString(),
expected.toString());
}
public void testCreateServerWithOptsWhenResponseIs2xx() throws Exception {
@ -208,21 +213,26 @@ public class ServerClientExpectTest extends BaseRestClientExpectTest<GleSYSClien
.put("Accept", "application/json")
.put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
.payload(newUrlEncodedFormPayload(ImmutableMultimap.<String, String>builder()
.put("cpucores", "1").put("memorysize", "512")
.put("datacenter", "Falkenberg")
.put("transfer", "50")
.put("rootpassword", "password")
.put("hostname", "jclouds-test")
.put("rootpassword", "password")
.put("datacenter", "Falkenberg")
.put("platform", "OpenVZ")
.put("templatename", "Ubuntu 32-bit")
.put("disksize", "5")
.put("memorysize", "512")
.put("cpucores", "1")
.put("transfer", "50")
.put("ip", "10.0.0.1")
.put("description", "Description-of-server")
.put("ip", "10.0.0.1").build())).build(),
.build())).build(),
HttpResponse.builder().statusCode(200).payload(payloadFromResource("/server_details.json")).build()).getServerClient();
CreateServerOptions options = CreateServerOptions.Builder.description("Description-of-server").ip("10.0.0.1");
assertEquals(client.createServer("Falkenberg", "OpenVZ", "jclouds-test", "Ubuntu 32-bit", 5, 512, 1, "password", 50, options), expectedServerDetails());
assertEquals(client.createServerWithHostnameAndRootPassword(ServerSpec.builder().datacenter("Falkenberg")
.platform("OpenVZ").templateName("Ubuntu 32-bit").diskSizeGB(5).memorySizeMB(512).cpuCores(1).transfer(50)
.build(), "jclouds-test", "password", options), expectedServerDetails());
}
@Test

View File

@ -30,6 +30,7 @@ import org.jclouds.glesys.GleSYSAsyncClient;
import org.jclouds.glesys.GleSYSClient;
import org.jclouds.glesys.domain.Server;
import org.jclouds.glesys.domain.ServerDetails;
import org.jclouds.glesys.domain.ServerSpec;
import org.jclouds.glesys.domain.ServerStatus;
import org.jclouds.glesys.features.DomainClient;
import org.jclouds.glesys.features.ServerClient;
@ -93,7 +94,10 @@ public class BaseGleSYSClientLiveTest {
protected ServerStatusChecker createServer(String hostName) {
ServerClient client = context.getApi().getServerClient();
ServerDetails testServer = client.createServer("Falkenberg", "OpenVZ", hostName, "Ubuntu 10.04 LTS 32-bit", 5, 512, 1, "password", 50);
ServerDetails testServer = client.createServerWithHostnameAndRootPassword(
ServerSpec.builder().datacenter("Falkenberg").platform("OpenVZ").templateName("Ubuntu 10.04 LTS 32-bit")
.diskSizeGB(5).memorySizeMB(512).cpuCores(1).transfer(50).build(), hostName, "password");
assertNotNull(testServer.getId());
assertEquals(testServer.getHostname(), hostName);