From eb000b2c1d25a3f18f9d773c7a28c613369681ad Mon Sep 17 00:00:00 2001 From: Andrew Bayer Date: Fri, 14 Feb 2014 14:23:30 -0800 Subject: [PATCH] JCLOUDS-467. Properly iterate over node names for EC2 instance creation. --- .../ec2/compute/EC2ComputeService.java | 48 ++++---- .../compute/EC2ComputeServiceExpectTest.java | 69 +++++++++-- .../describe_instances_running-named.xml | 114 +++++++++++++++++- 3 files changed, 197 insertions(+), 34 deletions(-) diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java index 9a81a94efa..2dc2197ef0 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Strings.emptyToNull; import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Iterables.transform; +import static com.google.common.collect.Lists.newArrayList; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_DELIMITER; @@ -32,16 +33,33 @@ import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_GENERATE_INSTA import static org.jclouds.ec2.util.Tags.resourceToTagsAsMap; import static org.jclouds.util.Predicates2.retry; +import javax.inject.Named; +import javax.inject.Provider; +import javax.inject.Singleton; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicReference; -import javax.inject.Named; -import javax.inject.Provider; -import javax.inject.Singleton; - +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableMultimap.Builder; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.Inject; import org.jclouds.Constants; import org.jclouds.aws.util.AWSUtils; import org.jclouds.collect.Memoized; @@ -85,23 +103,6 @@ import org.jclouds.ec2.util.TagFilterBuilder; import org.jclouds.scriptbuilder.functions.InitAdminAccess; import org.jclouds.util.Strings2; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableMultimap.Builder; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.inject.Inject; - /** * @author Adrian Cole */ @@ -175,12 +176,13 @@ public class EC2ComputeService extends BaseComputeService { Map instancesById = Maps.uniqueIndex(input, instanceId); ImmutableSet.Builder builder = ImmutableSet. builder(); + List namesToUse = newArrayList(nodeNames); if (generateInstanceNames && !common.containsKey("Name")) { for (Map.Entry entry : instancesById.entrySet()) { String id = entry.getKey(); String name; - if (!nodeNames.isEmpty()) { - name = Iterables.get(nodeNames, 0); + if (!namesToUse.isEmpty()) { + name = namesToUse.remove(0); } else { name = id.replaceAll(".*-", group + "-"); } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java index cdc832d457..c2d386b581 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceExpectTest.java @@ -22,6 +22,7 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import javax.ws.rs.core.MediaType; +import java.util.Set; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; @@ -190,8 +191,8 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest assertEquals(node.getCredentials().getUser(), "ec2-user", "User should be ec2-user"); } - public void testCreateNodeWithSpecifiedName() throws Exception { - HttpRequest createNamedTagsRequest = + public void testCreateThreeNodesWithSpecifiedName() throws Exception { + HttpRequest createFirstNamedTagRequest = formSigner.filter(HttpRequest.builder() .method("POST") .endpoint("https://ec2.us-east-1.amazonaws.com/") @@ -199,7 +200,7 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest .payload( payloadFromStringWithContentType( "Action=CreateTags" + - "&ResourceId.1=i-2baa5550" + + "&ResourceId.1=i-2ba64342" + "&Signature=Trp5e5%2BMqeBeBZbLYa9s9gxahQ9nkx6ETfsGl82IV8Y%3D" + "&SignatureMethod=HmacSHA256" + "&SignatureVersion=2" + @@ -211,6 +212,46 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest "application/x-www-form-urlencoded")) .build()); + HttpRequest createSecondNamedTagRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/") + .addHeader("Host", "ec2.us-east-1.amazonaws.com") + .payload( + payloadFromStringWithContentType( + "Action=CreateTags" + + "&ResourceId.1=i-2bc64242" + + "&Signature=Trp5e5%2BMqeBeBZbLYa9s9gxahQ9nkx6ETfsGl82IV8Y%3D" + + "&SignatureMethod=HmacSHA256" + + "&SignatureVersion=2" + + "&Tag.1.Key=Name" + + "&Tag.1.Value=second-node" + + "&Timestamp=2012-04-16T15%3A54%3A08.897Z" + + "&Version=2010-08-31" + + "&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded")) + .build()); + + HttpRequest createThirdNamedTagRequest = + formSigner.filter(HttpRequest.builder() + .method("POST") + .endpoint("https://ec2.us-east-1.amazonaws.com/") + .addHeader("Host", "ec2.us-east-1.amazonaws.com") + .payload( + payloadFromStringWithContentType( + "Action=CreateTags" + + "&ResourceId.1=i-2be64332" + + "&Signature=Trp5e5%2BMqeBeBZbLYa9s9gxahQ9nkx6ETfsGl82IV8Y%3D" + + "&SignatureMethod=HmacSHA256" + + "&SignatureVersion=2" + + "&Tag.1.Key=Name" + + "&Tag.1.Value=third-node" + + "&Timestamp=2012-04-16T15%3A54%3A08.897Z" + + "&Version=2010-08-31" + + "&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded")) + .build()); + HttpResponse describeNamedInstanceResponse = HttpResponse.builder().statusCode(200) .payload(payloadFromResourceWithContentType( @@ -226,19 +267,27 @@ public class EC2ComputeServiceExpectTest extends BaseEC2ComputeServiceExpectTest requestResponseMap.put(describeSecurityGroupRequest, describeSecurityGroupResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequest22, authorizeSecurityGroupIngressResponse); requestResponseMap.put(authorizeSecurityGroupIngressRequestGroup, authorizeSecurityGroupIngressResponse); - requestResponseMap.put(runInstancesRequest, runInstancesResponse); + requestResponseMap.put(runThreeInstancesRequest, runThreeInstancesResponse); requestResponseMap.put(describeInstanceRequest, describeNamedInstanceResponse); - requestResponseMap.put(describeInstanceMultiIdsRequest, describeInstanceMultiIdsResponse); + requestResponseMap.put(describeInstanceThreeIdsRequest, describeInstanceThreeIdsResponse); requestResponseMap.put(describeImageRequest, describeImagesResponse); - requestResponseMap.put(createNamedTagsRequest, createTagsResponse); + requestResponseMap.put(createFirstNamedTagRequest, createTagsResponse); + requestResponseMap.put(createSecondNamedTagRequest, createTagsResponse); + requestResponseMap.put(createThirdNamedTagRequest, createTagsResponse); ComputeService apiThatCreatesNode = requestsSendResponses(requestResponseMap.build()); - NodeMetadata node = Iterables.getOnlyElement(apiThatCreatesNode.createNodesInGroup("test", 1, - blockUntilRunning(false).overrideLoginUser("ec2-user").nodeNames(ImmutableSet.of("test-node")))); - assertEquals(node.getCredentials().getUser(), "ec2-user"); - assertNotNull(node.getCredentials().getPrivateKey()); + Set nodes = apiThatCreatesNode.createNodesInGroup("test", 3, + maxCount(3).blockUntilRunning(false).overrideLoginUser("ec2-user").nodeNames(ImmutableSet.of("test-node", "second-node", "third-node"))); + + NodeMetadata node = Iterables.get(nodes, 0); assertEquals(node.getName(), "test-node"); + + NodeMetadata secondNode = Iterables.get(nodes, 1); + assertEquals(secondNode.getName(), "second-node"); + + NodeMetadata thirdNode = Iterables.get(nodes, 2); + assertEquals(thirdNode.getName(), "third-node"); } //FIXME - issue-1051 diff --git a/apis/ec2/src/test/resources/describe_instances_running-named.xml b/apis/ec2/src/test/resources/describe_instances_running-named.xml index 4f46adae0c..4a432794ee 100644 --- a/apis/ec2/src/test/resources/describe_instances_running-named.xml +++ b/apis/ec2/src/test/resources/describe_instances_running-named.xml @@ -13,7 +13,7 @@ - i-2baa5550 + i-2ba64342 ami-aecd60c7 16 @@ -68,6 +68,118 @@ xen + + i-2bc64242 + ami-aecd60c7 + + 16 + running + + ip-10-28-89-195.ec2.internal + ec2-50-16-1-166.compute-1.amazonaws.com + + jclouds#mygroup2#81 + 0 + + t1.micro + 2012-08-02T04:28:30.000Z + + us-east-1e + + default + + aki-88aa75e1 + + disabled + + 10.28.89.195 + 50.16.1.166 + + + sg-3c6ef654 + jclouds#mygroup2 + + + x86_64 + ebs + /dev/sda1 + + + /dev/sda1 + + vol-f2d7c993 + attached + 2012-08-02T04:28:56.000Z + true + + + + paravirtual + + + + Name + second-node + + + xen + + + i-2be64332 + ami-aecd60c7 + + 16 + running + + ip-10-28-89-195.ec2.internal + ec2-50-16-1-166.compute-1.amazonaws.com + + jclouds#mygroup2#81 + 0 + + t1.micro + 2012-08-02T04:28:30.000Z + + us-east-1e + + default + + aki-88aa75e1 + + disabled + + 10.28.89.195 + 50.16.1.166 + + + sg-3c6ef654 + jclouds#mygroup2 + + + x86_64 + ebs + /dev/sda1 + + + /dev/sda1 + + vol-f2d7c993 + attached + 2012-08-02T04:28:56.000Z + true + + + + paravirtual + + + + Name + third-node + + + xen +