Updated Branches: refs/heads/master 13f38d628 -> a42d62cb8
JCLOUDS-349 createServerByZone squashed commit create server in a selected availability zone + live and expect tests Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/a42d62cb Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/a42d62cb Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/a42d62cb Branch: refs/heads/master Commit: a42d62cb888041127dba275400620e31c1249764 Parents: 13f38d6 Author: istolber <[email protected]> Authored: Wed Oct 16 13:11:04 2013 +0200 Committer: Everett Toews <[email protected]> Committed: Fri Oct 18 09:50:27 2013 -0500 ---------------------------------------------------------------------- .../nova/v2_0/options/CreateServerOptions.java | 120 +++++++++++-------- .../nova/v2_0/features/ServerApiExpectTest.java | 24 ++++ .../nova/v2_0/features/ServerApiLiveTest.java | 42 +++++++ .../src/test/resources/new_server_in_zone.json | 41 +++++++ 4 files changed, 177 insertions(+), 50 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/a42d62cb/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java index c6d4220..e3937aa 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/options/CreateServerOptions.java @@ -16,28 +16,6 @@ */ package org.jclouds.openstack.nova.v2_0.options; -import static com.google.common.base.Objects.equal; -import static com.google.common.base.Objects.toStringHelper; -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.Strings.emptyToNull; -import static com.google.common.io.BaseEncoding.base64; - -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.jclouds.http.HttpRequest; -import org.jclouds.openstack.nova.v2_0.NovaApi; -import org.jclouds.openstack.nova.v2_0.domain.Server; -import org.jclouds.rest.MapBinder; -import org.jclouds.rest.binders.BindToJsonPayload; - import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; import com.google.common.base.Optional; @@ -46,11 +24,30 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import org.jclouds.http.HttpRequest; +import org.jclouds.openstack.nova.v2_0.NovaApi; +import org.jclouds.openstack.nova.v2_0.domain.Server; +import org.jclouds.rest.MapBinder; +import org.jclouds.rest.binders.BindToJsonPayload; + +import javax.inject.Inject; +import javax.inject.Named; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import static com.google.common.base.Objects.equal; +import static com.google.common.base.Objects.toStringHelper; +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.Strings.emptyToNull; +import static com.google.common.io.BaseEncoding.base64; /** - * * @author Adrian Cole - * + * @author Inbar Stolberg */ public class CreateServerOptions implements MapBinder { @Inject @@ -78,7 +75,7 @@ public class CreateServerOptions implements MapBinder { public String getPath() { return path; } - + @Override public boolean equals(Object object) { if (this == object) { @@ -112,6 +109,7 @@ public class CreateServerOptions implements MapBinder { private byte[] userData; private String diskConfig; private Set<String> networks = ImmutableSet.of(); + private String availabilityZone; @Override public boolean equals(Object object) { @@ -121,9 +119,10 @@ public class CreateServerOptions implements MapBinder { if (object instanceof CreateServerOptions) { final CreateServerOptions other = CreateServerOptions.class.cast(object); return equal(keyName, other.keyName) && equal(securityGroupNames, other.securityGroupNames) - && equal(metadata, other.metadata) && equal(personality, other.personality) - && equal(adminPass, other.adminPass) && equal(diskConfig, other.diskConfig) - && equal(adminPass, other.adminPass) && equal(networks, other.networks); + && equal(metadata, other.metadata) && equal(personality, other.personality) + && equal(adminPass, other.adminPass) && equal(diskConfig, other.diskConfig) + && equal(adminPass, other.adminPass) && equal(networks, other.networks) + && equal(availabilityZone, other.availabilityZone); } else { return false; } @@ -131,7 +130,7 @@ public class CreateServerOptions implements MapBinder { @Override public int hashCode() { - return Objects.hashCode(keyName, securityGroupNames, metadata, personality, adminPass, networks); + return Objects.hashCode(keyName, securityGroupNames, metadata, personality, adminPass, networks, availabilityZone); } protected ToStringHelper string() { @@ -150,6 +149,7 @@ public class CreateServerOptions implements MapBinder { toString.add("userData", userData == null ? null : new String(userData)); if (!networks.isEmpty()) toString.add("networks", networks); + toString.add("availability_zone", availabilityZone == null ? null : availabilityZone); return toString; } @@ -162,6 +162,8 @@ public class CreateServerOptions implements MapBinder { final String name; final String imageRef; final String flavorRef; + @Named("availability_zone") + String availabilityZone; String adminPass; Map<String, String> metadata; List<File> personality; @@ -192,6 +194,8 @@ public class CreateServerOptions implements MapBinder { server.personality = personality; if (keyName != null) server.key_name = keyName; + if (availabilityZone != null) + server.availabilityZone = availabilityZone; if (userData != null) server.user_data = base64().encode(userData); if (securityGroupNames.size() > 0) { @@ -291,8 +295,8 @@ public class CreateServerOptions implements MapBinder { * by instance scripts. */ public CreateServerOptions userData(byte[] userData) { - this.userData = userData; - return this; + this.userData = userData; + return this; } /** @@ -302,7 +306,11 @@ public class CreateServerOptions implements MapBinder { public String getKeyPairName() { return keyName; } - + + public String getAvailabilityZone() { + return availabilityZone; + } + /** * @see #getKeyPairName() */ @@ -310,33 +318,38 @@ public class CreateServerOptions implements MapBinder { this.keyName = keyName; return this; } - + + /** + * @see #getAvailabilityZone() + */ + public CreateServerOptions availabilityZone(String availabilityZone) { + this.availabilityZone = availabilityZone; + return this; + } + /** - * * Security groups the user specified to run servers with. - * + * <p/> * <h3>Note</h3> - * + * <p/> * This requires that {@link NovaApi#getSecurityGroupExtensionForZone(String)} to return * {@link Optional#isPresent present} */ public Set<String> getSecurityGroupNames() { return securityGroupNames; } - + /** - * * Get custom networks specified for the server. + * * @return A set of uuids defined by Neutron (previously Quantum) * @see <a href="https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Network">Neutron Networks<a/> - * */ public Set<String> getNetworks() { return networks; } /** - * * @see #getSecurityGroupNames */ public CreateServerOptions securityGroupNames(String... securityGroupNames) { @@ -354,12 +367,12 @@ public class CreateServerOptions implements MapBinder { } /** - * When you create a server from an image with the diskConfig value set to - * {@link Server#DISK_CONFIG_AUTO}, the server is built with a single partition that is expanded to - * the disk size of the flavor selected. When you set the diskConfig attribute to - * {@link Server#DISK_CONFIG_MANUAL}, the server is built by using the partition scheme and file + * When you create a server from an image with the diskConfig value set to + * {@link Server#DISK_CONFIG_AUTO}, the server is built with a single partition that is expanded to + * the disk size of the flavor selected. When you set the diskConfig attribute to + * {@link Server#DISK_CONFIG_MANUAL}, the server is built by using the partition scheme and file * system that is in the source image. - * <p/> + * <p/> * If the target flavor disk is larger, remaining disk space is left unpartitioned. A server inherits the diskConfig * attribute from the image from which it is created. However, you can override the diskConfig value when you create * a server. This field is only present if the Disk Config extension is installed in your OpenStack deployment. @@ -367,7 +380,7 @@ public class CreateServerOptions implements MapBinder { public String getDiskConfig() { return diskConfig; } - + /** * @see #getDiskConfig */ @@ -375,9 +388,8 @@ public class CreateServerOptions implements MapBinder { this.diskConfig = diskConfig; return this; } - + /** - * * @see #getNetworks */ public CreateServerOptions networks(String... networks) { @@ -399,7 +411,7 @@ public class CreateServerOptions implements MapBinder { /** * @see CreateServerOptions#writeFileToPath */ - public static CreateServerOptions writeFileToPath(byte[] contents,String path) { + public static CreateServerOptions writeFileToPath(byte[] contents, String path) { CreateServerOptions options = new CreateServerOptions(); return options.writeFileToPath(contents, path); } @@ -424,7 +436,7 @@ public class CreateServerOptions implements MapBinder { CreateServerOptions options = new CreateServerOptions(); return options.keyPairName(keyName); } - + /** * @see CreateServerOptions#getSecurityGroupNames */ @@ -464,6 +476,14 @@ public class CreateServerOptions implements MapBinder { CreateServerOptions options = new CreateServerOptions(); return CreateServerOptions.class.cast(options.networks(networks)); } + + /** + * @see org.jclouds.openstack.nova.v2_0.options.CreateServerOptions#getAvailabilityZone() + */ + public static CreateServerOptions availabilityZone(String availabilityZone) { + CreateServerOptions options = new CreateServerOptions(); + return options.availabilityZone(availabilityZone); + } } @Override http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/a42d62cb/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java index 95f6865..6778fa4 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java @@ -103,6 +103,30 @@ public class ServerApiExpectTest extends BaseNovaApiExpectTest { new ParseCreatedServerTest().expected().toString()); } + public void testCreateServerInAvailabilityZoneWhenResponseIs202() throws Exception { + HttpRequest createServer = HttpRequest + .builder() + .method("POST") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType( + "{\"server\":{\"name\":\"test-e92\",\"imageRef\":\"1241\",\"flavorRef\":\"100\",\"availability_zone\":\"nova\"}}","application/json")) + .build(); + + + HttpResponse createServerResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted") + .payload(payloadFromResourceWithContentType("/new_server_in_zone.json","application/json; charset=UTF-8")).build(); + + NovaApi apiWithNewServer = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, createServer, createServerResponse); + + CreateServerOptions options = new CreateServerOptions().availabilityZone("nova"); + + assertEquals(apiWithNewServer.getServerApiForZone("az-1.region-a.geo-1").create("test-e92", "1241", "100", options).toString(), + new ParseCreatedServerTest().expected().toString()); + } + public void testCreateServerWithSecurityGroupsWhenResponseIs202() throws Exception { HttpRequest createServer = HttpRequest http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/a42d62cb/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiLiveTest.java ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiLiveTest.java index fdd12f1..492c98a 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiLiveTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiLiveTest.java @@ -22,7 +22,9 @@ import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import org.jclouds.openstack.nova.v2_0.domain.Server; +import org.jclouds.openstack.nova.v2_0.domain.ServerCreated; import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest; +import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions; import org.jclouds.openstack.v2_0.domain.Link.Relation; import org.jclouds.openstack.v2_0.domain.Resource; import org.jclouds.openstack.v2_0.predicates.LinkPredicates; @@ -34,6 +36,7 @@ import com.google.common.collect.Iterables; * Tests behavior of {@link ServerApi} * * @author Adrian Cole + * @author Inbar Stolberg */ @Test(groups = "live", testName = "ServerApiLiveTest") public class ServerApiLiveTest extends BaseNovaApiLiveTest { @@ -72,6 +75,45 @@ public class ServerApiLiveTest extends BaseNovaApiLiveTest { } } + @Test + public void testCreateInAvailabilityZone() { + String serverId = null; + for (String zoneId : zones) { + ServerApi serverApi = api.getServerApiForZone(zoneId); + try { + serverId = createServer(zoneId, "nova", Server.Status.ACTIVE).getId(); + Server server = serverApi.get(serverId); + assertEquals(server.getStatus(), Server.Status.ACTIVE); + } finally { + serverApi.delete(serverId); + } + } + } + + @Test + public void testCreateInWrongAvailabilityZone() { + String serverId = null; + for (String zoneId : zones) { + ServerApi serverApi = api.getServerApiForZone(zoneId); + try { + serverId = createServer(zoneId, "err", Server.Status.ERROR).getId(); + Server server = serverApi.get(serverId); + assertEquals(server.getStatus(), Server.Status.ERROR); + } finally { + serverApi.delete(serverId); + } + } + } + + private Server createServer(String regionId, String availabilityZoneId, Server.Status serverStatus) { + ServerApi serverApi = api.getServerApiForZone(regionId); + CreateServerOptions options = new CreateServerOptions(); + options = options.availabilityZone(availabilityZoneId); + ServerCreated server = serverApi.create(hostName, imageIdForZone(regionId), flavorRefForZone(regionId), options); + blockUntilServerInState(server.getId(), serverApi, serverStatus); + return serverApi.get(server.getId()); + } + private void checkResource(Resource resource) { assertNotNull(resource.getId()); assertNotNull(resource.getName()); http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/a42d62cb/apis/openstack-nova/src/test/resources/new_server_in_zone.json ---------------------------------------------------------------------- diff --git a/apis/openstack-nova/src/test/resources/new_server_in_zone.json b/apis/openstack-nova/src/test/resources/new_server_in_zone.json new file mode 100644 index 0000000..71fb1f2 --- /dev/null +++ b/apis/openstack-nova/src/test/resources/new_server_in_zone.json @@ -0,0 +1,41 @@ +{ + "server": { + "status": "BUILD(scheduling)", + "updated": "2012-03-19T06:21:13Z", + "hostId": "", + "user_id": "54297837463082", + "name": "test-e92", + "links": [{ + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/37936628937291/servers/71752", + "rel": "self" + }, { + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/servers/71752", + "rel": "bookmark" + }], + "addresses": {}, + "tenant_id": "37936628937291", + "image": { + "id": "1241", + "links": [{ + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/images/1241", + "rel": "bookmark" + }] + }, + "created": "2012-03-19T06:21:13Z", + "uuid": "47491020-6a78-4f63-9475-23195ac4515c", + "accessIPv4": "", + "accessIPv6": "", + "key_name": null, + "adminPass": "ZWuHcmTMQ7eXoHeM", + "flavor": { + "id": "100", + "links": [{ + "href": "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/37936628937291/flavors/100", + "rel": "bookmark" + }] + }, + "config_drive": "", + "id": 71752, + "metadata": {} + } +} \ No newline at end of file
