diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreateSecurityGroupIfNeeded.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreateSecurityGroupIfNeeded.java index 030fdc95fa..73d182776e 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreateSecurityGroupIfNeeded.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreateSecurityGroupIfNeeded.java @@ -49,7 +49,7 @@ public class CreateSecurityGroupIfNeeded extends CacheLoader { @Override public KeyPair load(RegionAndName from) { - return knownKeys.containsKey(from) ? knownKeys.get(from) : createNewKeyPairInRegion(from.getRegion(), - from.getName()); + if (knownKeys.containsKey(from)){ + return knownKeys.get(from); + } else { + KeyPair keyPair = createNewKeyPairInRegion(from.getRegion(), from.getName()); + knownKeys.put(new RegionAndName(from.getRegion(), keyPair.getKeyName()), keyPair); + knownKeys.put(from, keyPair); + return keyPair; + } } @VisibleForTesting diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java index baca5d70ae..892feaf252 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java @@ -18,6 +18,7 @@ */ package org.jclouds.ec2.compute.strategy; +import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import java.util.Map; @@ -62,10 +63,10 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions { public CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(Map knownKeys, Cache credentialsMap, @Named("SECURITY") Cache securityGroupMap, Provider optionsProvider) { - this.knownKeys=knownKeys; - this.credentialsMap = credentialsMap; - this.securityGroupMap = securityGroupMap; - this.optionsProvider = optionsProvider; + this.knownKeys = checkNotNull(knownKeys, "knownKeys"); + this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap"); + this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap"); + this.optionsProvider = checkNotNull(optionsProvider, "optionsProvider"); } public RunInstancesOptions execute(String region, String group, Template template) { @@ -120,7 +121,7 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions { KeyPair keyPair = KeyPair.builder().region(region).keyName(keyPairName).keyFingerprint("//TODO") .keyMaterial(options.getOverridingCredentials().credential).build(); - RegionAndName key = new RegionAndName(region, group); + RegionAndName key = new RegionAndName(region, keyPairName); knownKeys.put(key, keyPair); credentialsMap.invalidate(key); } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPairTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPairTest.java index a03a77aacf..f7363db6a6 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPairTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CreateUniqueKeyPairTest.java @@ -149,7 +149,12 @@ public class CreateUniqueKeyPairTest { expect(keyClient.createKeyPairInRegion("region", "jclouds#group#region#1")).andThrow(new IllegalStateException()); expect(uniqueIdSupplier.get()).andReturn("2"); expect(keyClient.createKeyPairInRegion("region", "jclouds#group#region#2")).andReturn(pair); + expect(pair.getKeyName()).andReturn("jclouds#group#region#2").times(2); + // seeding the cache explicitly. both by keyName and also by group + expect(knownKeys.put(new RegionAndName("region", "jclouds#group#region#2"), pair)).andReturn(null); + expect(knownKeys.put(new RegionAndName("region", "group"), pair)).andReturn(null); + replay(pair); replay(client); replay(knownKeys); replay(keyClient); @@ -159,6 +164,7 @@ public class CreateUniqueKeyPairTest { assertEquals(parser.load(new RegionAndName("region", "group")), pair); + verify(pair); verify(client); verify(knownKeys); verify(keyClient); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java index bc7412e6e5..c98b53ed16 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java @@ -289,10 +289,10 @@ public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { expect(options.getOverridingCredentials()).andReturn(new Credentials(null, "MyRsa")).atLeastOnce(); expect( strategy.knownKeys.put( - new RegionAndName(region, tag), + new RegionAndName(region, userSuppliedKeyPair), KeyPair.builder().region(region).keyName(userSuppliedKeyPair).keyFingerprint("//TODO") .keyMaterial("MyRsa").build())).andReturn(null); - strategy.credentialsMap.invalidate(new RegionAndName(region, tag)); + strategy.credentialsMap.invalidate(new RegionAndName(region, userSuppliedKeyPair)); expect(options.getRunScript()).andReturn(Statements.exec("echo foo")); expect(strategy.credentialsMap.getUnchecked(new RegionAndName(region, userSuppliedKeyPair))).andReturn(keyPair); diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java index 1eff004f23..2ee7fc70e2 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java @@ -31,6 +31,7 @@ import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; import org.jclouds.aws.ec2.compute.suppliers.CallForImages; import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.aws.ec2.domain.RegionNameAndPublicKeyMaterial; +import org.jclouds.aws.ec2.functions.CreatePlacementGroupIfNeeded; import org.jclouds.aws.ec2.functions.ImportOrReturnExistingKeypair; import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable; import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted; @@ -115,7 +116,7 @@ public class AWSEC2ComputeServiceDependenciesModule extends EC2ComputeServiceDep @Provides @Singleton @Named("PLACEMENT") - protected Cache placementGroupMap(CreateSecurityGroupIfNeeded in) { + protected Cache placementGroupMap(CreatePlacementGroupIfNeeded in) { return CacheBuilder.newBuilder().build(in); } diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java index 5f981fa14a..fcf396f61e 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java @@ -117,8 +117,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions } @Override - protected String createOrImportKeyPair(String region, String group, TemplateOptions options) { - RegionAndName key = new RegionAndName(region, "jclouds#" + group); + public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String group, TemplateOptions options) { + RegionAndName key = new RegionAndName(region, group); KeyPair pair = knownKeys.get(key); if (pair != null) return pair.getKeyName(); @@ -132,7 +132,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions if (hasPublicKeyMaterial.apply(options)) { logger.warn("to avoid creating temporary keys in aws-ec2, use templateOption overrideLoginCredentialWith(id_rsa)"); } - return super.createOrImportKeyPair(region, group, options); + return super.createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, options); } return pair.getKeyName(); } @@ -163,14 +163,14 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions } }; - + @Override protected boolean userSpecifiedTheirOwnGroups(TemplateOptions options) { return options instanceof AWSEC2TemplateOptions && AWSEC2TemplateOptions.class.cast(options).getGroupIds().size() > 0 || super.userSpecifiedTheirOwnGroups(options); } - + @Override protected void addSecurityGroups(String region, String group, Template template, RunInstancesOptions instanceOptions) { AWSEC2TemplateOptions awsTemplateOptions = AWSEC2TemplateOptions.class.cast(template.getOptions()); diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java index b63c9f4590..358a1e2929 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java @@ -34,15 +34,15 @@ import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.logging.Logger; -import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.cache.CacheLoader; /** * * @author Adrian Cole */ @Singleton -public class CreatePlacementGroupIfNeeded implements Function { +public class CreatePlacementGroupIfNeeded extends CacheLoader { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; @@ -57,7 +57,7 @@ public class CreatePlacementGroupIfNeeded implements Function