Issue 77: completed functionality, except error handling, version, and limits

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1834 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-07-23 09:13:05 +00:00
parent 3571be7a16
commit abf4b13b4d
11 changed files with 744 additions and 10 deletions

View File

@ -39,12 +39,17 @@ import org.jclouds.http.functions.ReturnFalseOn404;
import org.jclouds.rackspace.cloudservers.binders.BackupScheduleBinder;
import org.jclouds.rackspace.cloudservers.binders.ChangeAdminPassBinder;
import org.jclouds.rackspace.cloudservers.binders.ChangeServerNameBinder;
import org.jclouds.rackspace.cloudservers.binders.ConfirmResizeBinder;
import org.jclouds.rackspace.cloudservers.binders.CreateImageBinder;
import org.jclouds.rackspace.cloudservers.binders.RebootTypeBinder;
import org.jclouds.rackspace.cloudservers.binders.ResizeBinder;
import org.jclouds.rackspace.cloudservers.binders.RevertResizeBinder;
import org.jclouds.rackspace.cloudservers.binders.ShareIpBinder;
import org.jclouds.rackspace.cloudservers.domain.Addresses;
import org.jclouds.rackspace.cloudservers.domain.BackupSchedule;
import org.jclouds.rackspace.cloudservers.domain.Flavor;
import org.jclouds.rackspace.cloudservers.domain.Image;
import org.jclouds.rackspace.cloudservers.domain.RebootType;
import org.jclouds.rackspace.cloudservers.domain.Server;
import org.jclouds.rackspace.cloudservers.domain.SharedIpGroup;
import org.jclouds.rackspace.cloudservers.functions.IpAddress;
@ -66,6 +71,7 @@ import org.jclouds.rackspace.cloudservers.functions.ReturnSharedIpGroupNotFoundO
import org.jclouds.rackspace.cloudservers.options.CreateServerOptions;
import org.jclouds.rackspace.cloudservers.options.CreateSharedIpGroupOptions;
import org.jclouds.rackspace.cloudservers.options.ListOptions;
import org.jclouds.rackspace.cloudservers.options.RebuildServerOptions;
import org.jclouds.rackspace.filters.AuthenticateRequest;
import org.jclouds.rest.EntityParam;
import org.jclouds.rest.ExceptionParser;
@ -141,15 +147,27 @@ public interface CloudServersConnection {
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 reboot function allows for either a soft or hard reboot of a server.
* <p/>
* Status Transition:
* <p/>
* ACTIVE - REBOOT - ACTIVE (soft reboot)
* <p/>
* ACTIVE - HARD_REBOOT - ACTIVE (hard reboot)
*
* @param rebootType
* 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.
*/
@POST
@Query(key = "format", value = "json")
@Path("/servers/{id}/action")
@ExceptionParser(ReturnFalseOn404.class)
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
// (400), badMediaType(415),buildInProgress (409), overLimit (403)
boolean rebootServer(@PathParam("id") int id,
@EntityParam(RebootTypeBinder.class) RebootType rebootType);
/**
* The resize function converts an existing server to a different flavor, in essence, scaling the
@ -157,7 +175,61 @@ public interface CloudServersConnection {
* 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.
* <p/>
* Status Transition:
* <p/>
* ACTIVE - QUEUE_RESIZE - PREP_RESIZE - VERIFY_RESIZE
* <p/>
* ACTIVE - QUEUE_RESIZE - ACTIVE (on error)
*/
@POST
@Query(key = "format", value = "json")
@Path("/servers/{id}/action")
@ExceptionParser(ReturnFalseOn404.class)
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
// (503), overLimit (413), resizeNotAllowed (403)
boolean resizeServer(@PathParam("id") int id, @EntityParam(ResizeBinder.class) int flavorId);
/**
* 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.
* <p/>
* Status Transition:
* <p/>
* VERIFY_RESIZE - ACTIVE
*/
@POST
@Query(key = "format", value = "json")
@Path("/servers/{id}/action")
@ExceptionParser(ReturnFalseOn404.class)
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
// (503), overLimit (413), resizeNotAllowed (403)
boolean confirmResizeServer(@PathParam("id") @EntityParam(ConfirmResizeBinder.class) int id);
/**
* 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 reverted, at which time the
* original server is removed. All resizes are automatically reverted after 24 hours if they are
* not reverted or reverted.
* <p/>
* Status Transition:
* <p/>
* VERIFY_RESIZE - ACTIVE
*/
@POST
@Query(key = "format", value = "json")
@Path("/servers/{id}/action")
@ExceptionParser(ReturnFalseOn404.class)
// TODO:cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
// (503), overLimit (413), resizeNotAllowed (403)
boolean revertResizeServer(@PathParam("id") @EntityParam(RevertResizeBinder.class) int id);
/**
* This operation asynchronously provisions a new server. The progress of this operation depends
@ -180,6 +252,31 @@ public interface CloudServersConnection {
Server createServer(@MapEntityParam("name") String name, @MapEntityParam("imageId") int imageId,
@MapEntityParam("flavorId") int flavorId, CreateServerOptions... options);
/**
* The rebuild function removes all data on the server and replaces it with the specified image.
* Server ID and IP addresses remain the same.
* <p/>
* Status Transition:
* <p/>
* ACTIVE - REBUILD - ACTIVE
* <p/>
* ACTIVE - REBUILD - ERROR (on error)
* <p/>
*
* @param options
* - imageId is an optional argument. If it is not specified, the server is rebuilt
* with the original imageId.
*/
@POST
@Query(key = "format", value = "json")
@Path("/servers/{id}/action")
@ExceptionParser(ReturnFalseOn404.class)
@MapBinder(RebuildServerOptions.class)
// TODO: cloudServersFault (400, 500), serviceUnavailable (503), unauthorized (401), badRequest
// (400), badMediaType(415), itemNotFound (404), buildInProgress (409), serverCapacityUnavailable
// (503), overLimit (413)
boolean rebuildServer(@PathParam("id") int id, RebuildServerOptions... options);
/**
* /** This operation allows you share an IP address to the specified server
* <p/>

View File

@ -0,0 +1,48 @@
/**
*
* 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 java.util.Collections;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.EntityBinder;
/**
*
* @author Adrian Cole
*
*/
public class ConfirmResizeBinder implements EntityBinder {
public void addEntityToRequest(Object toBind, HttpRequest request) {
request.setEntity("{\"confirmResize\":null}");
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
Collections.singletonList("{\"confirmResize\":null}".getBytes().length + ""));
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
Collections.singletonList(MediaType.APPLICATION_JSON));
}
}

View File

@ -0,0 +1,55 @@
/**
*
* 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 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 org.jclouds.rackspace.cloudservers.domain.RebootType;
import com.google.common.collect.ImmutableMap;
/**
*
* @author Adrian Cole
*
*/
public class RebootTypeBinder extends JsonBinder {
@Override
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
throw new IllegalStateException("Reboot doesn't take map parameters");
}
@Override
public void addEntityToRequest(Object toBind, HttpRequest request) {
checkArgument(toBind instanceof RebootType, "this binder is only valid for RebootTypes!");
super.addEntityToRequest(ImmutableMap.of("reboot", ImmutableMap.of("type", checkNotNull(
toBind, "type"))), request);
}
}

View File

@ -0,0 +1,54 @@
/**
*
* 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 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 ResizeBinder extends JsonBinder {
@Override
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
throw new IllegalStateException("Resize doesn't take map parameters");
}
@Override
public void addEntityToRequest(Object toBind, HttpRequest request) {
checkArgument(toBind instanceof Integer, "this binder is only valid for integers!");
super.addEntityToRequest(ImmutableMap.of("resize", ImmutableMap.of("flavorId",
(Integer) checkNotNull(toBind, "flavorId"))), request);
}
}

View File

@ -0,0 +1,48 @@
/**
*
* 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 java.util.Collections;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.EntityBinder;
/**
*
* @author Adrian Cole
*
*/
public class RevertResizeBinder implements EntityBinder {
public void addEntityToRequest(Object toBind, HttpRequest request) {
request.setEntity("{\"revertResize\":null}");
request.getHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
Collections.singletonList("{\"revertResize\":null}".getBytes().length + ""));
request.getHeaders().replaceValues(HttpHeaders.CONTENT_TYPE,
Collections.singletonList(MediaType.APPLICATION_JSON));
}
}

View File

@ -23,6 +23,10 @@
*/
package org.jclouds.rackspace.cloudservers.domain;
/**
*
* @author Adrian Cole
*/
public enum RebootType {
HARD, SOFT;

View File

@ -0,0 +1,79 @@
/**
*
* 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.options;
import static com.google.common.base.Preconditions.checkArgument;
import java.util.Map;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.binders.JsonBinder;
import com.google.common.collect.ImmutableMap;
import com.google.inject.internal.Maps;
/**
*
*
* @author Adrian Cole
*
*/
public class RebuildServerOptions extends JsonBinder {
Integer imageId;
@Override
public void addEntityToRequest(Map<String, String> postParams, HttpRequest request) {
Map<String, Integer> image = Maps.newHashMap();
if (imageId != null)
image.put("imageId", imageId);
super.addEntityToRequest(ImmutableMap.of("rebuild", image), request);
}
@Override
public void addEntityToRequest(Object toBind, HttpRequest request) {
throw new IllegalStateException("RebuildServer is a POST operation");
}
/**
*
* @param id
* of the image to rebuild the server with.
*/
public RebuildServerOptions withImage(int id) {
checkArgument(id > 0, "server id must be a positive number");
this.imageId = id;
return this;
}
public static class Builder {
/**
* @see RebuildServerOptions#withImage(int)
*/
public static RebuildServerOptions withImage(int id) {
RebuildServerOptions options = new RebuildServerOptions();
return options.withImage(id);
}
}
}

View File

@ -26,6 +26,7 @@ package org.jclouds.rackspace.cloudservers;
import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Builder.withFile;
import static org.jclouds.rackspace.cloudservers.options.CreateSharedIpGroupOptions.Builder.withServer;
import static org.jclouds.rackspace.cloudservers.options.ListOptions.Builder.withDetails;
import static org.jclouds.rackspace.cloudservers.options.RebuildServerOptions.Builder.withImage;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_KEY;
import static org.jclouds.rackspace.reference.RackspaceConstants.PROPERTY_RACKSPACE_USER;
import static org.testng.Assert.assertEquals;
@ -47,6 +48,7 @@ import org.jclouds.rackspace.cloudservers.domain.DailyBackup;
import org.jclouds.rackspace.cloudservers.domain.Flavor;
import org.jclouds.rackspace.cloudservers.domain.Image;
import org.jclouds.rackspace.cloudservers.domain.ImageStatus;
import org.jclouds.rackspace.cloudservers.domain.RebootType;
import org.jclouds.rackspace.cloudservers.domain.Server;
import org.jclouds.rackspace.cloudservers.domain.ServerStatus;
import org.jclouds.rackspace.cloudservers.domain.SharedIpGroup;
@ -284,6 +286,7 @@ public class CloudServersConnectionLiveTest {
private InetAddress ip;
private int serverId2;
private String adminPass2;
private int imageId;
@Test(timeOut = 5 * 60 * 1000)
public void testCreateServer() throws Exception {
@ -324,6 +327,20 @@ public class CloudServersConnectionLiveTest {
Thread.sleep(10 * 1000);
}
private void blockUntilServerVerifyResize(int serverId) throws InterruptedException {
Server currentDetails = null;
for (currentDetails = connection.getServer(serverId); currentDetails.getStatus() != ServerStatus.VERIFY_RESIZE; currentDetails = connection
.getServer(serverId)) {
System.out.printf("blocking on status verify resize%n%s%n", currentDetails);
Thread.sleep(5 * 1000);
}
/**
* [Web Hosting #119335]
*/
System.out.printf("awaiting daemons to verify resize %n%s%n", currentDetails);
Thread.sleep(10 * 1000);
}
private void blockUntilImageActive(int imageId) throws InterruptedException {
Image currentDetails = null;
for (currentDetails = connection.getImage(imageId); currentDetails.getStatus() != ImageStatus.ACTIVE; currentDetails = connection
@ -515,12 +532,51 @@ public class CloudServersConnectionLiveTest {
Image image = connection.createImageFromServer("hoofie", serverId);
assertEquals("hoofie", image.getName());
assertEquals(new Integer(serverId), image.getServerId());
int imageId = image.getId();
imageId = image.getId();
blockUntilImageActive(imageId);
}
// must be last!. do not rely on positional order.
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testCreateImage")
public void testRebuildServer() throws Exception {
assertTrue(connection.rebuildServer(serverId, withImage(imageId)));
blockUntilServerActive(serverId);
// issue Web Hosting #119580 imageId comes back incorrect after rebuild
// assertEquals(new Integer(imageId), connection.getServer(serverId).getImageId());
}
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testRebuildServer")
public void testRebootHard() throws Exception {
assertTrue(connection.rebootServer(serverId, RebootType.HARD));
blockUntilServerActive(serverId);
}
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testRebootHard")
public void testRebootSoft() throws Exception {
assertTrue(connection.rebootServer(serverId, RebootType.SOFT));
blockUntilServerActive(serverId);
}
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testRebootSoft")
public void testRevertResize() throws Exception {
assertTrue(connection.resizeServer(serverId, 2));
blockUntilServerVerifyResize(serverId);
assertTrue(connection.revertResizeServer(serverId));
blockUntilServerActive(serverId);
assertEquals(new Integer(1), connection.getServer(serverId).getFlavorId());
}
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = "testRebootSoft")
public void testConfirmResize() throws Exception {
assertTrue(connection.resizeServer(serverId2, 2));
blockUntilServerVerifyResize(serverId2);
assertTrue(connection.confirmResizeServer(serverId2));
blockUntilServerActive(serverId2);
assertEquals(new Integer(2), connection.getServer(serverId2).getFlavorId());
}
// must be last!. do not rely on positional order.
@Test(timeOut = 5 * 60 * 1000, dependsOnMethods = { "testRebootSoft", "testRevertResize",
"testConfirmResize" })
void deleteServers() {
if (serverId > 0) {
connection.deleteServer(serverId);

View File

@ -27,6 +27,7 @@ import static org.jclouds.rackspace.cloudservers.options.CreateServerOptions.Bui
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.CreateSharedIpGroupOptions.Builder.withServer;
import static org.jclouds.rackspace.cloudservers.options.RebuildServerOptions.Builder.withImage;
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.assertEquals;
@ -51,6 +52,7 @@ import org.jclouds.http.functions.ReturnTrueIf2xx;
import org.jclouds.rackspace.Authentication;
import org.jclouds.rackspace.cloudservers.domain.BackupSchedule;
import org.jclouds.rackspace.cloudservers.domain.DailyBackup;
import org.jclouds.rackspace.cloudservers.domain.RebootType;
import org.jclouds.rackspace.cloudservers.domain.WeeklyBackup;
import org.jclouds.rackspace.cloudservers.functions.ParseAddressesFromGsonResponse;
import org.jclouds.rackspace.cloudservers.functions.ParseBackupScheduleFromGsonResponse;
@ -70,6 +72,7 @@ import org.jclouds.rackspace.cloudservers.functions.ReturnSharedIpGroupNotFoundO
import org.jclouds.rackspace.cloudservers.options.CreateServerOptions;
import org.jclouds.rackspace.cloudservers.options.CreateSharedIpGroupOptions;
import org.jclouds.rackspace.cloudservers.options.ListOptions;
import org.jclouds.rackspace.cloudservers.options.RebuildServerOptions;
import org.jclouds.rest.JaxrsAnnotationProcessor;
import org.jclouds.rest.config.JaxrsModule;
import org.joda.time.DateTime;
@ -753,6 +756,119 @@ public class CloudServersConnectionTest {
assertNotNull(processor.getMapEntityBinderOrNull(method, new Object[] { "", 2 }));
}
private static final Class<? extends RebuildServerOptions[]> rebuildServerOptionsVarargsClass = new RebuildServerOptions[] {}
.getClass();
public void testRebuildServer() throws SecurityException, NoSuchMethodException {
Method method = CloudServersConnection.class.getMethod("rebuildServer", int.class,
rebuildServerOptionsVarargsClass);
URI endpoint = URI.create("http://localhost");
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 3 });
assertEquals("{\"rebuild\":{}}", httpMethod.getEntity());
validateRebuildServer(method, httpMethod);
}
public void testRebuildServerWithImage() throws SecurityException, NoSuchMethodException {
Method method = CloudServersConnection.class.getMethod("rebuildServer", int.class,
rebuildServerOptionsVarargsClass);
URI endpoint = URI.create("http://localhost");
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 3,
withImage(2) });
assertEquals("{\"rebuild\":{\"imageId\":2}}", httpMethod.getEntity());
validateRebuildServer(method, httpMethod);
}
private void validateRebuildServer(Method method, HttpRequest httpMethod) {
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/3/action");
assertEquals(httpMethod.getEndpoint().getQuery(), "format=json");
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
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(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
ReturnFalseOn404.class);
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
assertNotNull(processor.getMapEntityBinderOrNull(method, new Object[] { "",
new RebuildServerOptions[] { withImage(2) } }));
}
public void testReboot() throws SecurityException, NoSuchMethodException {
Method method = CloudServersConnection.class.getMethod("rebootServer", int.class,
RebootType.class);
URI endpoint = URI.create("http://localhost");
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2,
RebootType.HARD });
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2/action");
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
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("{\"reboot\":{\"type\":\"HARD\"}}", httpMethod.getEntity());
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
ReturnFalseOn404.class);
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
}
public void testResize() throws SecurityException, NoSuchMethodException {
Method method = CloudServersConnection.class.getMethod("resizeServer", int.class, int.class);
URI endpoint = URI.create("http://localhost");
HttpRequest httpMethod = processor.createRequest(endpoint, method, new Object[] { 2, 3 });
assertEquals(httpMethod.getEndpoint().getHost(), "localhost");
assertEquals(httpMethod.getEndpoint().getPath(), "/servers/2/action");
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
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("{\"resize\":{\"flavorId\":3}}", httpMethod.getEntity());
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
ReturnFalseOn404.class);
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
}
public void testConfirmResize() throws SecurityException, NoSuchMethodException {
Method method = CloudServersConnection.class.getMethod("confirmResizeServer", 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().getPath(), "/servers/2/action");
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
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("{\"confirmResize\":null}", httpMethod.getEntity());
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
ReturnFalseOn404.class);
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
}
public void testRevertResize() throws SecurityException, NoSuchMethodException {
Method method = CloudServersConnection.class.getMethod("revertResizeServer", 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().getPath(), "/servers/2/action");
assertEquals(httpMethod.getMethod(), HttpMethod.POST);
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("{\"revertResize\":null}", httpMethod.getEntity());
assertEquals(processor.createExceptionParserOrNullIfNotFound(method).getClass(),
ReturnFalseOn404.class);
assertEquals(processor.createResponseParser(method).getClass(), ReturnTrueIf2xx.class);
}
JaxrsAnnotationProcessor processor;
@BeforeClass

View File

@ -0,0 +1,94 @@
/**
*
* 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.RebootTypeBinder;
import org.jclouds.rackspace.cloudservers.domain.RebootType;
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 RebootTypeBinder}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "cloudservers.RebootTypeBinderTest")
public class RebootTypeBinderTest {
Injector injector = Guice.createInjector(new ParserModule());
@Test(expectedExceptions = IllegalStateException.class)
public void testPostIsIncorrect() {
RebootTypeBinder binder = new RebootTypeBinder();
injector.injectMembers(binder);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
binder.addEntityToRequest(ImmutableMap.of("adminPass", "foo"), request);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMustBeRebootType() {
RebootTypeBinder binder = new RebootTypeBinder();
injector.injectMembers(binder);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
binder.addEntityToRequest(new File("foo"), request);
}
@Test
public void testHard() {
RebootTypeBinder binder = new RebootTypeBinder();
injector.injectMembers(binder);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
binder.addEntityToRequest(RebootType.HARD, request);
assertEquals("{\"reboot\":{\"type\":\"HARD\"}}", request.getEntity());
}
@Test
public void testSoft() {
RebootTypeBinder binder = new RebootTypeBinder();
injector.injectMembers(binder);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
binder.addEntityToRequest(RebootType.SOFT, request);
assertEquals("{\"reboot\":{\"type\":\"SOFT\"}}", request.getEntity());
}
@Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class })
public void testNullIsBad() {
RebootTypeBinder binder = new RebootTypeBinder();
injector.injectMembers(binder);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
binder.addEntityToRequest(null, request);
}
}

View File

@ -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.options;
import static org.jclouds.rackspace.cloudservers.options.RebuildServerOptions.Builder.withImage;
import static org.testng.Assert.assertEquals;
import java.net.URI;
import java.util.HashMap;
import org.jclouds.http.HttpMethod;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.config.ParserModule;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code ParseFlavorFromGsonResponse}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "cloudsharedIpGroups.RebuildServerOptionsTest")
public class RebuildServerOptionsTest {
Injector injector = Guice.createInjector(new ParserModule());
@Test
public void testAddEntityToRequestMapOfStringStringHttpRequest() {
RebuildServerOptions options = new RebuildServerOptions();
HttpRequest request = buildRequest(options);
assertEquals("{\"rebuild\":{}}", request.getEntity());
}
private HttpRequest buildRequest(RebuildServerOptions options) {
injector.injectMembers(options);
HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("/"));
options.addEntityToRequest(new HashMap<String, String>(), request);
return request;
}
@Test
public void testWithServer() {
RebuildServerOptions options = new RebuildServerOptions();
options.withImage(3);
HttpRequest request = buildRequest(options);
assertRebuild(request);
}
@Test
public void testWithServerStatic() {
RebuildServerOptions options = withImage(3);
HttpRequest request = buildRequest(options);
assertRebuild(request);
}
private void assertRebuild(HttpRequest request) {
assertEquals("{\"rebuild\":{\"imageId\":3}}", request.getEntity());
}
}