From ddc1a30b55afb0bb7f957a7f562552e6045ed6ab Mon Sep 17 00:00:00 2001 From: Alex Yarmula Date: Sat, 27 Feb 2010 21:09:04 -0800 Subject: [PATCH] finished with server functionality; extended tests --- .../gogrid/binders/BindIdsToQueryParams.java | 6 +- .../binders/BindNamesToQueryParams.java | 6 +- .../org/jclouds/gogrid/domain/Option.java | 16 ++- .../jclouds/gogrid/domain/PowerCommand.java | 31 +++++ .../org/jclouds/gogrid/domain/Server.java | 2 +- .../gogrid/domain/internal/ErrorResponse.java | 3 + .../ParseServerFromJsonResponse.java | 37 +++++ .../gogrid/handlers/GoGridErrorHandler.java | 5 +- .../gogrid/options/AddServerOptions.java | 31 +++++ .../gogrid/options/GetServerListOptions.java | 57 ++++++++ .../gogrid/reference/GoGridConstants.java | 3 +- .../gogrid/reference/GoGridQueryParams.java | 22 +++ .../services/GridServerAsyncClient.java | 54 +++++--- .../gogrid/services/GridServerClient.java | 65 ++++++++- .../handlers/GoGridErrorHandlerTest.java | 74 ++++++++++ .../jclouds/gogrid/mock/HttpCommandMock.java | 61 +++++++++ .../services/GridServerAsyncClientTest.java | 129 +++++++++++++++++- .../services/GridServerClientLiveTest.java | 18 +++ .../test/resources/test_error_handler.json | 16 +++ 19 files changed, 601 insertions(+), 35 deletions(-) create mode 100644 gogrid/src/main/java/org/jclouds/gogrid/domain/PowerCommand.java create mode 100644 gogrid/src/main/java/org/jclouds/gogrid/functions/ParseServerFromJsonResponse.java create mode 100644 gogrid/src/main/java/org/jclouds/gogrid/options/AddServerOptions.java create mode 100644 gogrid/src/main/java/org/jclouds/gogrid/options/GetServerListOptions.java create mode 100644 gogrid/src/main/java/org/jclouds/gogrid/reference/GoGridQueryParams.java create mode 100644 gogrid/src/test/java/org/jclouds/gogrid/handlers/GoGridErrorHandlerTest.java create mode 100644 gogrid/src/test/java/org/jclouds/gogrid/mock/HttpCommandMock.java create mode 100644 gogrid/src/test/resources/test_error_handler.json diff --git a/gogrid/src/main/java/org/jclouds/gogrid/binders/BindIdsToQueryParams.java b/gogrid/src/main/java/org/jclouds/gogrid/binders/BindIdsToQueryParams.java index cc86e9ede5..7f7f3e8b99 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/binders/BindIdsToQueryParams.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/binders/BindIdsToQueryParams.java @@ -7,7 +7,11 @@ import org.jclouds.rest.internal.GeneratedHttpRequest; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.gogrid.reference.GoGridQueryParams.ID_KEY; + /** + * Binds IDs to corresponding query parameters + * * @author Oleksiy Yarmula */ public class BindIdsToQueryParams implements Binder { @@ -35,7 +39,7 @@ public class BindIdsToQueryParams implements Binder { GeneratedHttpRequest generatedRequest = (GeneratedHttpRequest) request; for(Long id : names) { - generatedRequest.addQueryParam("id", checkNotNull(id.toString(), + generatedRequest.addQueryParam(ID_KEY, checkNotNull(id.toString(), /*or throw*/ "id must have a non-null value")); } diff --git a/gogrid/src/main/java/org/jclouds/gogrid/binders/BindNamesToQueryParams.java b/gogrid/src/main/java/org/jclouds/gogrid/binders/BindNamesToQueryParams.java index bf619c08c1..e3710bb433 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/binders/BindNamesToQueryParams.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/binders/BindNamesToQueryParams.java @@ -7,7 +7,11 @@ import org.jclouds.rest.internal.GeneratedHttpRequest; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.gogrid.reference.GoGridQueryParams.NAME_KEY; + /** + * Binds names to corresponding query parameters + * @author Oleksiy Yarmula */ public class BindNamesToQueryParams implements Binder { @@ -36,7 +40,7 @@ public class BindNamesToQueryParams implements Binder { GeneratedHttpRequest generatedRequest = (GeneratedHttpRequest) request; for(String name : names) { - generatedRequest.addQueryParam("name", name); + generatedRequest.addQueryParam(NAME_KEY, name); } } diff --git a/gogrid/src/main/java/org/jclouds/gogrid/domain/Option.java b/gogrid/src/main/java/org/jclouds/gogrid/domain/Option.java index 0a2e5a12cd..570db98929 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/domain/Option.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/domain/Option.java @@ -5,7 +5,7 @@ package org.jclouds.gogrid.domain; */ public class Option { - private long id; + private Long id; private String name; private String description; @@ -16,7 +16,15 @@ public class Option { public Option() { } - public Option(long id, String name, String description) { + public Option(Long id) { + this(id, null, null); + } + + public Option(String name) { + this(null, name, null); + } + + public Option(Long id, String name, String description) { this.id = id; this.name = name; this.description = description; @@ -41,8 +49,8 @@ public class Option { Option option = (Option) o; - if (id != option.id) return false; if (description != null ? !description.equals(option.description) : option.description != null) return false; + if (id != null ? !id.equals(option.id) : option.id != null) return false; if (name != null ? !name.equals(option.name) : option.name != null) return false; return true; @@ -50,7 +58,7 @@ public class Option { @Override public int hashCode() { - int result = (int) (id ^ (id >>> 32)); + int result = id != null ? id.hashCode() : 0; result = 31 * result + (name != null ? name.hashCode() : 0); result = 31 * result + (description != null ? description.hashCode() : 0); return result; diff --git a/gogrid/src/main/java/org/jclouds/gogrid/domain/PowerCommand.java b/gogrid/src/main/java/org/jclouds/gogrid/domain/PowerCommand.java new file mode 100644 index 0000000000..fea5bee07f --- /dev/null +++ b/gogrid/src/main/java/org/jclouds/gogrid/domain/PowerCommand.java @@ -0,0 +1,31 @@ +package org.jclouds.gogrid.domain; + +import com.google.common.base.CaseFormat; + +/** + * Server's state transition. + * + * Using this value, server's state will be changed + * to one of the following: + * + * + * @see org.jclouds.gogrid.services.GridServerClient#power(String, PowerCommand) + * @see + * + * @author Oleksiy Yarmula + */ +public enum PowerCommand { + START, + STOP /*NOTE: This is a hard shutdown, equivalent to powering off a server.*/, + RESTART; + + + @Override + public String toString() { + return name().toLowerCase(); + } +} diff --git a/gogrid/src/main/java/org/jclouds/gogrid/domain/Server.java b/gogrid/src/main/java/org/jclouds/gogrid/domain/Server.java index 1bbb1fecd4..62464d6c81 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/domain/Server.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/domain/Server.java @@ -30,7 +30,7 @@ public class Server implements Comparable { String description, Option state, Option type, Option ram, Option os, Ip ip, ServerImage image) { this.id = id; - isSandbox = sandbox; + this.isSandbox = sandbox; this.name = name; this.description = description; this.state = state; diff --git a/gogrid/src/main/java/org/jclouds/gogrid/domain/internal/ErrorResponse.java b/gogrid/src/main/java/org/jclouds/gogrid/domain/internal/ErrorResponse.java index 175fc228ca..5c1b8c0121 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/domain/internal/ErrorResponse.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/domain/internal/ErrorResponse.java @@ -1,11 +1,14 @@ package org.jclouds.gogrid.domain.internal; +import com.google.gson.annotations.SerializedName; + /** * @author Oleksiy Yarmula */ public class ErrorResponse { private String message; + @SerializedName("errorcode") private String errorCode; /** diff --git a/gogrid/src/main/java/org/jclouds/gogrid/functions/ParseServerFromJsonResponse.java b/gogrid/src/main/java/org/jclouds/gogrid/functions/ParseServerFromJsonResponse.java new file mode 100644 index 0000000000..472e41b868 --- /dev/null +++ b/gogrid/src/main/java/org/jclouds/gogrid/functions/ParseServerFromJsonResponse.java @@ -0,0 +1,37 @@ +package org.jclouds.gogrid.functions; + +import com.google.common.collect.Iterables; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.jclouds.gogrid.domain.Server; +import org.jclouds.gogrid.domain.internal.GenericResponseContainer; +import org.jclouds.http.functions.ParseJson; + +import javax.inject.Inject; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Type; + +/** + * @author Oleksiy Yarmula + */ +public class ParseServerFromJsonResponse extends ParseJson { + + @Inject + public ParseServerFromJsonResponse(Gson gson) { + super(gson); + } + + public Server apply(InputStream stream) { + Type setType = new TypeToken>() { + }.getType(); + GenericResponseContainer response; + try { + response = gson.fromJson(new InputStreamReader(stream, "UTF-8"), setType); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("jclouds requires UTF-8 encoding", e); + } + return Iterables.getOnlyElement(response.getList()); + } +} diff --git a/gogrid/src/main/java/org/jclouds/gogrid/handlers/GoGridErrorHandler.java b/gogrid/src/main/java/org/jclouds/gogrid/handlers/GoGridErrorHandler.java index 28ce16adef..b9b4673dfa 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/handlers/GoGridErrorHandler.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/handlers/GoGridErrorHandler.java @@ -31,10 +31,7 @@ public class GoGridErrorHandler implements HttpErrorHandler { Exception exception; ErrorResponse error = parseErrorFromContentOrNull(response.getContent()); switch (response.getStatusCode()) { - case 403: - exception = new AuthorizationException(command.getRequest(), - error.getMessage()); - break; + //more cases to be added default: exception = error != null ? new GoGridResponseException(command, response, error) : diff --git a/gogrid/src/main/java/org/jclouds/gogrid/options/AddServerOptions.java b/gogrid/src/main/java/org/jclouds/gogrid/options/AddServerOptions.java new file mode 100644 index 0000000000..88e0f39743 --- /dev/null +++ b/gogrid/src/main/java/org/jclouds/gogrid/options/AddServerOptions.java @@ -0,0 +1,31 @@ +package org.jclouds.gogrid.options; + +import org.jclouds.http.options.BaseHttpRequestOptions; + +import static com.google.common.base.Preconditions.checkState; +import static org.jclouds.gogrid.reference.GoGridQueryParams.*; + +/** + * @author Oleksiy Yarmula + */ +public class AddServerOptions extends BaseHttpRequestOptions { + + public AddServerOptions setDescription(String description) { + checkState(!queryParameters.containsKey(DESCRIPTION_KEY), "Can't have duplicate server description"); + queryParameters.put(DESCRIPTION_KEY, description); + return this; + } + + /** + * Make server a sandbox instance. + * By default, it's not. + * + * @return itself for convenience + */ + public AddServerOptions makeSandboxType() { + checkState(!queryParameters.containsKey(IS_SANDBOX_KEY), "Can only have one sandbox option per server"); + queryParameters.put(IS_SANDBOX_KEY, "true"); + return this; + } + +} diff --git a/gogrid/src/main/java/org/jclouds/gogrid/options/GetServerListOptions.java b/gogrid/src/main/java/org/jclouds/gogrid/options/GetServerListOptions.java new file mode 100644 index 0000000000..7952af58d5 --- /dev/null +++ b/gogrid/src/main/java/org/jclouds/gogrid/options/GetServerListOptions.java @@ -0,0 +1,57 @@ +package org.jclouds.gogrid.options; + +import org.jclouds.http.options.BaseHttpRequestOptions; + +import static com.google.common.base.Preconditions.*; +import static org.jclouds.gogrid.reference.GoGridQueryParams.SERVER_TYPE_KEY; +import static org.jclouds.gogrid.reference.GoGridQueryParams.IS_SANDBOX_KEY; + +/** + * @author Oleksiy Yarmula + */ +public class GetServerListOptions extends BaseHttpRequestOptions { + + public final static GetServerListOptions NONE = new GetServerListOptions(); + + public GetServerListOptions limitServerTypeTo(String serverType) { + checkState(!queryParameters.containsKey(SERVER_TYPE_KEY), "Can't have duplicate server type limit"); + queryParameters.put(SERVER_TYPE_KEY, serverType); + return this; + } + + public GetServerListOptions onlySandboxServers() { + checkState(!queryParameters.containsKey(IS_SANDBOX_KEY), "Can't have duplicate sandbox type limit"); + queryParameters.put(IS_SANDBOX_KEY, "true"); + return this; + } + + public GetServerListOptions excludeSandboxServers() { + checkState(!queryParameters.containsKey(IS_SANDBOX_KEY), "Can't have duplicate sandbox type limit"); + queryParameters.put(IS_SANDBOX_KEY, "false"); + return this; + } + + public static class Builder { + + public GetServerListOptions limitServerTypeTo(String serverType) { + GetServerListOptions getServerListOptions = new GetServerListOptions(); + getServerListOptions.limitServerTypeTo(checkNotNull(serverType)); + return getServerListOptions; + } + + public GetServerListOptions onlySandboxServers() { + GetServerListOptions getServerListOptions = new GetServerListOptions(); + getServerListOptions.onlySandboxServers(); + return getServerListOptions; + } + + public GetServerListOptions excludeSandboxServers() { + GetServerListOptions getServerListOptions = new GetServerListOptions(); + getServerListOptions.excludeSandboxServers(); + return getServerListOptions; + } + + } + + +} diff --git a/gogrid/src/main/java/org/jclouds/gogrid/reference/GoGridConstants.java b/gogrid/src/main/java/org/jclouds/gogrid/reference/GoGridConstants.java index afc22f518d..9e1da18cfe 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/reference/GoGridConstants.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/reference/GoGridConstants.java @@ -48,12 +48,11 @@ package org.jclouds.gogrid.reference; */ public interface GoGridConstants { public static final String PROPERTY_GOGRID_ENDPOINT = "jclouds.gogrid.endpoint"; - //TODO: see if "users" needs to be renamed to "apiKey" public static final String PROPERTY_GOGRID_USER = "jclouds.gogrid.api.key"; - //TODO: see if "password" needs to be renamed to "secret" public static final String PROPERTY_GOGRID_PASSWORD = "jclouds.gogrid.secret"; /** * how long do we wait before obtaining a new timestamp for requests. */ public static final String PROPERTY_GOGRID_SESSIONINTERVAL = "jclouds.gogrid.sessioninterval"; + } diff --git a/gogrid/src/main/java/org/jclouds/gogrid/reference/GoGridQueryParams.java b/gogrid/src/main/java/org/jclouds/gogrid/reference/GoGridQueryParams.java new file mode 100644 index 0000000000..dd150034f1 --- /dev/null +++ b/gogrid/src/main/java/org/jclouds/gogrid/reference/GoGridQueryParams.java @@ -0,0 +1,22 @@ +package org.jclouds.gogrid.reference; + +/** + * @author Oleksiy Yarmula + */ +public interface GoGridQueryParams { + + public static final String ID_KEY = "id"; + public static final String NAME_KEY = "name"; + public static final String SERVER_ID_OR_NAME_KEY = "server"; + public static final String SERVER_TYPE_KEY = "server.type"; + + public static final String IS_SANDBOX_KEY = "isSandbox"; + public static final String IMAGE_KEY = "image"; + public static final String IP_KEY = "ip"; + + public static final String SERVER_RAM_KEY = "server.ram"; + + public static final String DESCRIPTION_KEY = "server.ram"; + public static final String POWER_KEY = "power"; + +} diff --git a/gogrid/src/main/java/org/jclouds/gogrid/services/GridServerAsyncClient.java b/gogrid/src/main/java/org/jclouds/gogrid/services/GridServerAsyncClient.java index 88a6d03aa3..2f0cd5d8a2 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/services/GridServerAsyncClient.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/services/GridServerAsyncClient.java @@ -1,21 +1,3 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ /** * * Copyright (C) 2010 Cloud Conscious, LLC. @@ -45,17 +27,23 @@ import com.google.common.util.concurrent.ListenableFuture; import javax.ws.rs.GET; import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; import org.jclouds.gogrid.GoGrid; import org.jclouds.gogrid.binders.BindIdsToQueryParams; import org.jclouds.gogrid.binders.BindNamesToQueryParams; +import org.jclouds.gogrid.domain.PowerCommand; import org.jclouds.gogrid.domain.Server; import org.jclouds.gogrid.filters.SharedKeyLiteAuthentication; +import org.jclouds.gogrid.functions.ParseServerFromJsonResponse; import org.jclouds.gogrid.functions.ParseServerListFromJsonResponse; +import org.jclouds.gogrid.options.AddServerOptions; +import org.jclouds.gogrid.options.GetServerListOptions; import org.jclouds.rest.annotations.*; import java.util.Set; +import static org.jclouds.gogrid.reference.GoGridQueryParams.*; import static org.jclouds.gogrid.reference.GoGridHeaders.VERSION; /** @@ -75,7 +63,7 @@ public interface GridServerAsyncClient { @GET @ResponseParser(ParseServerListFromJsonResponse.class) @Path("/grid/server/list") - ListenableFuture> getServerList(); + ListenableFuture> getServerList(GetServerListOptions... getServerListOptions); @GET @ResponseParser(ParseServerListFromJsonResponse.class) @@ -86,4 +74,32 @@ public interface GridServerAsyncClient { @ResponseParser(ParseServerListFromJsonResponse.class) @Path("/grid/server/get") ListenableFuture> getServersById(@BinderParam(BindIdsToQueryParams.class) Long... ids); + + @GET + @ResponseParser(ParseServerFromJsonResponse.class) + @Path("/grid/server/add") + ListenableFuture addServer(@QueryParam(NAME_KEY) String name, + @QueryParam(IMAGE_KEY) String image, + @QueryParam(SERVER_RAM_KEY) String ram, + @QueryParam(IP_KEY) String ip, + AddServerOptions... addServerOptions); + + @GET + @ResponseParser(ParseServerFromJsonResponse.class) + @Path("/grid/server/power") + ListenableFuture power(@QueryParam(SERVER_ID_OR_NAME_KEY) String idOrName, + @QueryParam(POWER_KEY) PowerCommand power); + + @GET + @ResponseParser(ParseServerFromJsonResponse.class) + @Path("/grid/server/delete") + ListenableFuture deleteById(@QueryParam(ID_KEY) Long id); + + @GET + @ResponseParser(ParseServerFromJsonResponse.class) + @Path("/grid/server/delete") + ListenableFuture deleteByName(@QueryParam(NAME_KEY) String name); + + + } diff --git a/gogrid/src/main/java/org/jclouds/gogrid/services/GridServerClient.java b/gogrid/src/main/java/org/jclouds/gogrid/services/GridServerClient.java index 8510665daa..87675da1d8 100644 --- a/gogrid/src/main/java/org/jclouds/gogrid/services/GridServerClient.java +++ b/gogrid/src/main/java/org/jclouds/gogrid/services/GridServerClient.java @@ -27,7 +27,10 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import org.jclouds.concurrent.Timeout; +import org.jclouds.gogrid.domain.PowerCommand; import org.jclouds.gogrid.domain.Server; +import org.jclouds.gogrid.options.AddServerOptions; +import org.jclouds.gogrid.options.GetServerListOptions; /** * Provides synchronous access to GoGrid. @@ -42,7 +45,14 @@ import org.jclouds.gogrid.domain.Server; @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) public interface GridServerClient { - Set getServerList(); + /** + * Retrieves the list of all servers. + * + * The result can be narrowed down by providing the options. + * @param getServerListOptions options to narrow down the result + * @return servers found by the request + */ + Set getServerList(GetServerListOptions... getServerListOptions); /** * Retrieves the server(s) by unique name(s). @@ -64,5 +74,58 @@ public interface GridServerClient { */ Set getServersById(Long... ids); + /** + * Adds a server with specified attributes + * + * @param name name of the server + * @param image + * image (id or name) + * @param ram + * ram type (id or name) + * @param ip + * ip address + * @param addServerOptions + * options to make it a sandbox instance or/and description + * @return created server + */ + Server addServer(String name, + String image, + String ram, + String ip, + AddServerOptions... addServerOptions); + + /** + * Changes the server's state according to {@link PowerCommand} + * + * @param idOrName + * id or name of the server to apply the command + * @param power + * new desired state + * @return server immediately after applying the command + */ + Server power(String idOrName, + PowerCommand power); + + /** + * Deletes the server by Id + * + * @param id + * id of the server to delete + * @return server before the command is executed + */ + Server deleteById(Long id); + + /** + * Deletes the server by name; + * + * NOTE: Using this parameter may generate an + * error if one or more servers share a non-unique name. + * + * @param name + * name of the server to be deleted + * + * @return server before the command is executed + */ + Server deleteByName(String name); } diff --git a/gogrid/src/test/java/org/jclouds/gogrid/handlers/GoGridErrorHandlerTest.java b/gogrid/src/test/java/org/jclouds/gogrid/handlers/GoGridErrorHandlerTest.java new file mode 100644 index 0000000000..f096c72f2c --- /dev/null +++ b/gogrid/src/test/java/org/jclouds/gogrid/handlers/GoGridErrorHandlerTest.java @@ -0,0 +1,74 @@ +package org.jclouds.gogrid.handlers; + +import static org.testng.Assert.*; + +import com.google.gson.GsonBuilder; +import org.jclouds.gogrid.functions.ParseErrorFromJsonResponse; +import org.jclouds.gogrid.mock.HttpCommandMock; +import org.jclouds.http.*; +import org.testng.TestException; +import org.testng.annotations.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + + +/** + * Tests that the GoGridErrorHandler is + * correctly handling the exceptions. + * + * @author Oleksiy Yarmula + */ +public class GoGridErrorHandlerTest { + + @Test + public void testHandler() { + InputStream is = getClass().getResourceAsStream("/test_error_handler.json"); + + GoGridErrorHandler handler = + new GoGridErrorHandler(new ParseErrorFromJsonResponse(new GsonBuilder().create())); + + HttpCommand command = createHttpCommand(); + handler.handleError(command, new HttpResponse(is)); + + Exception createdException = command.getException(); + + assertNotNull(createdException, "There should've been an exception generated"); + String message = createdException.getMessage(); + assertTrue(message.contains("No object found that matches your input criteria."), + "Didn't find the expected error cause in the exception message"); + assertTrue(message.contains("IllegalArgumentException"), + "Didn't find the expected error code in the exception message"); + + //make sure the InputStream is closed + try { + is.available(); + throw new TestException("Stream wasn't closed by the GoGridErrorHandler when it should've"); + } catch(IOException e) { + //this is the excepted output + } + } + + HttpCommand createHttpCommand() { + return new HttpCommandMock() { + private Exception exception; + + @Override + public void setException(Exception exception) { + this.exception = exception; + } + + @Override + public Exception getException() { + return exception; + } + }; + } + + InputStream createInputStreamFromString(String s) { + return new ByteArrayInputStream(s.getBytes()); + } + + +} diff --git a/gogrid/src/test/java/org/jclouds/gogrid/mock/HttpCommandMock.java b/gogrid/src/test/java/org/jclouds/gogrid/mock/HttpCommandMock.java new file mode 100644 index 0000000000..6760e67239 --- /dev/null +++ b/gogrid/src/test/java/org/jclouds/gogrid/mock/HttpCommandMock.java @@ -0,0 +1,61 @@ +package org.jclouds.gogrid.mock; + +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpRequest; + +/** + * @author Oleksiy Yarmula + */ +public class HttpCommandMock implements HttpCommand { + + @Override + public int incrementRedirectCount() { + return 0; + } + + @Override + public int getRedirectCount() { + return 0; + } + + @Override + public boolean isReplayable() { + return false; + } + + @Override + public void changeHostAndPortTo(String host, int port) { + } + + @Override + public void changeToGETRequest() { + } + + @Override + public void changePathTo(String newPath) { + } + + @Override + public int incrementFailureCount() { + return 0; + } + + @Override + public int getFailureCount() { + return 0; + } + + @Override + public HttpRequest getRequest() { + return null; + } + + @Override + public void setException(Exception exception) { + } + + @Override + public Exception getException() { + return null; + } +} diff --git a/gogrid/src/test/java/org/jclouds/gogrid/services/GridServerAsyncClientTest.java b/gogrid/src/test/java/org/jclouds/gogrid/services/GridServerAsyncClientTest.java index 83ef8dc1d2..d578203f06 100644 --- a/gogrid/src/test/java/org/jclouds/gogrid/services/GridServerAsyncClientTest.java +++ b/gogrid/src/test/java/org/jclouds/gogrid/services/GridServerAsyncClientTest.java @@ -52,7 +52,11 @@ import javax.inject.Singleton; import com.google.common.collect.Iterables; import org.jclouds.gogrid.GoGrid; +import org.jclouds.gogrid.domain.PowerCommand; import org.jclouds.gogrid.filters.SharedKeyLiteAuthentication; +import org.jclouds.gogrid.functions.ParseServerFromJsonResponse; +import org.jclouds.gogrid.options.AddServerOptions; +import org.jclouds.gogrid.options.GetServerListOptions; import org.jclouds.gogrid.services.GridServerAsyncClient; import org.jclouds.logging.Logger; import org.jclouds.logging.Logger.LoggerFactory; @@ -78,8 +82,8 @@ import com.google.inject.TypeLiteral; public class GridServerAsyncClientTest extends RestClientTest { @Test - public void testGetServerList() throws NoSuchMethodException, IOException { - Method method = GridServerAsyncClient.class.getMethod("getServerList"); + public void testGetServerListNoOptions() throws NoSuchMethodException, IOException { + Method method = GridServerAsyncClient.class.getMethod("getServerList", GetServerListOptions[].class); GeneratedHttpRequest httpRequest = processor.createRequest(method); assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/list?v=1.3 HTTP/1.1"); @@ -101,6 +105,32 @@ public class GridServerAsyncClientTest extends RestClientTest httpRequest = processor.createRequest(method, + new GetServerListOptions.Builder().onlySandboxServers()); + + assertRequestLineEquals(httpRequest, + "GET https://api.gogrid.com/api/grid/server/list?v=1.3&isSandbox=true HTTP/1.1"); + assertHeadersEqual(httpRequest, ""); + assertPayloadEquals(httpRequest, null); + + assertResponseParserClassEquals(method, httpRequest, ParseServerListFromJsonResponse.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpRequest); + Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + + assertRequestLineEquals(httpRequest, + "GET https://api.gogrid.com/api/grid/server/list?" + + "v=1.3&isSandbox=true&sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + + "HTTP/1.1"); + assertHeadersEqual(httpRequest, ""); + assertPayloadEquals(httpRequest, null); + } + @Test public void testGetServersByName() throws NoSuchMethodException, IOException { @@ -154,6 +184,101 @@ public class GridServerAsyncClientTest extends RestClientTest httpRequest = + processor.createRequest(method, "serverName", "img55", + "memory", "127.0.0.1"); + + assertRequestLineEquals(httpRequest, + "GET https://api.gogrid.com/api/grid/server/add?v=1.3&" + + "name=serverName&server.ram=memory&image=img55&ip=127.0.0.1 " + + "HTTP/1.1"); + assertHeadersEqual(httpRequest, ""); + assertPayloadEquals(httpRequest, null); + + assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpRequest); + Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + + assertRequestLineEquals(httpRequest, + "GET https://api.gogrid.com/api/grid/server/add?" + + "v=1.3&name=serverName&server.ram=memory&" + + "image=img55&ip=127.0.0.1&" + + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + + "HTTP/1.1"); + assertHeadersEqual(httpRequest, ""); + assertPayloadEquals(httpRequest, null); + } + + + @Test + public void testPowerServer() throws NoSuchMethodException, IOException { + Method method = GridServerAsyncClient.class.getMethod("power", String.class, PowerCommand.class); + GeneratedHttpRequest httpRequest = + processor.createRequest(method, "PowerServer", PowerCommand.RESTART); + + assertRequestLineEquals(httpRequest, + "GET https://api.gogrid.com/api/grid/server/power?v=1.3&" + + "server=PowerServer&power=restart " + + "HTTP/1.1"); + assertHeadersEqual(httpRequest, ""); + assertPayloadEquals(httpRequest, null); + + assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpRequest); + Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + + assertRequestLineEquals(httpRequest, + "GET https://api.gogrid.com/api/grid/server/power?v=1.3&" + + "server=PowerServer&power=restart&" + + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + + "HTTP/1.1"); + assertHeadersEqual(httpRequest, ""); + assertPayloadEquals(httpRequest, null); + } + + + @Test + public void testDeleteByName() throws NoSuchMethodException, IOException { + Method method = GridServerAsyncClient.class.getMethod("deleteByName", String.class); + GeneratedHttpRequest httpRequest = + processor.createRequest(method, "PowerServer"); + + assertRequestLineEquals(httpRequest, + "GET https://api.gogrid.com/api/grid/server/delete?v=1.3&" + + "name=PowerServer " + + "HTTP/1.1"); + assertHeadersEqual(httpRequest, ""); + assertPayloadEquals(httpRequest, null); + + assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(httpRequest); + Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + + assertRequestLineEquals(httpRequest, + "GET https://api.gogrid.com/api/grid/server/delete?v=1.3&" + + "name=PowerServer&" + + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + + "HTTP/1.1"); + assertHeadersEqual(httpRequest, ""); + assertPayloadEquals(httpRequest, null); + } + @Override protected void checkFilters(GeneratedHttpRequest httpMethod) { diff --git a/gogrid/src/test/java/org/jclouds/gogrid/services/GridServerClientLiveTest.java b/gogrid/src/test/java/org/jclouds/gogrid/services/GridServerClientLiveTest.java index f4ac5017dc..c10a1f6513 100644 --- a/gogrid/src/test/java/org/jclouds/gogrid/services/GridServerClientLiveTest.java +++ b/gogrid/src/test/java/org/jclouds/gogrid/services/GridServerClientLiveTest.java @@ -27,12 +27,15 @@ import static com.google.common.base.Preconditions.checkNotNull; import org.jclouds.gogrid.GoGridClient; import org.jclouds.gogrid.GoGridContextFactory; +import org.jclouds.gogrid.domain.PowerCommand; import org.jclouds.gogrid.domain.Server; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; import java.util.Set; +import static org.testng.Assert.assertNotNull; + /** * Tests behavior of {@code GoGridClient} @@ -71,4 +74,19 @@ public class GridServerClientLiveTest { assert (response.size() > 0); } + @Test + public void testAddServer() { + Server createdServer = client.getServerClient().addServer("ServerCreatedFromAPI", + "GSI-f8979644-e646-4711-ad58-d98a5fa3612c", + "1", + "204.51.240.189"); + assertNotNull(createdServer); + } + + @Test + public void testRestart() { + Server createdServer = client.getServerClient().power("PowerServer", PowerCommand.RESTART); + assertNotNull(createdServer); + } + } diff --git a/gogrid/src/test/resources/test_error_handler.json b/gogrid/src/test/resources/test_error_handler.json new file mode 100644 index 0000000000..05f7083edc --- /dev/null +++ b/gogrid/src/test/resources/test_error_handler.json @@ -0,0 +1,16 @@ +{ + "list": [ + { + "object": "error", + "message": "No object found that matches your input criteria.", + "errorcode": "IllegalArgumentException" + } + ], + "summary": { + "total": 1, + "start": 0, + "returned": 1 + }, + "status": "failure", + "method": "/grid/server/get" +} \ No newline at end of file