EMMA Coverage Report (generated Mon Oct 17 05:41:20 EDT 2011)
[all classes][org.jclouds.ec2.compute.strategy]

COVERAGE SUMMARY FOR SOURCE FILE [CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java]

nameclass, %method, %block, %line, %
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java100% (1/1)88%  (7/8)84%  (290/344)87%  (54/62)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions100% (1/1)88%  (7/8)84%  (290/344)87%  (54/62)
getOptionsProvider (): Provider 0%   (0/1)0%   (0/3)0%   (0/1)
createOrImportKeyPair (String, String, TemplateOptions): String 100% (1/1)40%  (25/63)44%  (4/9)
execute (String, String, Template): RunInstancesOptions 100% (1/1)81%  (57/70)86%  (12/14)
CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions (Function, Concurre... 100% (1/1)100% (27/27)100% (6/6)
addSecurityGroups (String, String, Template, RunInstancesOptions): void 100% (1/1)100% (12/12)100% (3/3)
createNewKeyPairUnlessUserSpecifiedOtherwise (String, String, TemplateOptions... 100% (1/1)100% (95/95)100% (18/18)
getSecurityGroupsForTagAndOptions (String, String, TemplateOptions): Set 100% (1/1)100% (60/60)100% (10/10)
userSpecifiedTheirOwnGroups (TemplateOptions): boolean 100% (1/1)100% (14/14)100% (1/1)

1/**
2 * Licensed to jclouds, Inc. (jclouds) under one or more
3 * contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  jclouds licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.jclouds.ec2.compute.strategy;
20 
21import static com.google.common.base.Preconditions.checkArgument;
22import static com.google.common.base.Preconditions.checkNotNull;
23import static com.google.common.base.Preconditions.checkState;
24import static org.jclouds.crypto.SshKeys.fingerprintPrivateKey;
25import static org.jclouds.crypto.SshKeys.sha1PrivateKey;
26 
27import java.util.Set;
28import java.util.concurrent.ConcurrentMap;
29 
30import javax.inject.Inject;
31import javax.inject.Named;
32import javax.inject.Provider;
33import javax.inject.Singleton;
34 
35import org.jclouds.compute.domain.Template;
36import org.jclouds.compute.options.TemplateOptions;
37import org.jclouds.ec2.compute.domain.RegionAndName;
38import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules;
39import org.jclouds.ec2.compute.options.EC2TemplateOptions;
40import org.jclouds.ec2.domain.BlockDeviceMapping;
41import org.jclouds.ec2.domain.KeyPair;
42import org.jclouds.ec2.options.RunInstancesOptions;
43import org.jclouds.javax.annotation.Nullable;
44 
45import com.google.common.annotations.VisibleForTesting;
46import com.google.common.base.Function;
47import com.google.common.cache.Cache;
48import com.google.common.collect.ImmutableSet;
49import com.google.common.collect.ImmutableSet.Builder;
50 
51/**
52 * 
53 * @author Adrian Cole
54 */
55@Singleton
56public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
57   @VisibleForTesting
58   public Function<RegionAndName, KeyPair> makeKeyPair;
59   @VisibleForTesting
60   public final ConcurrentMap<RegionAndName, KeyPair> credentialsMap;
61   @VisibleForTesting
62   public final Cache<RegionAndName, String> securityGroupMap;
63   @VisibleForTesting
64   public final Provider<RunInstancesOptions> optionsProvider;
65 
66   @Inject
67   public CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(Function<RegionAndName, KeyPair> makeKeyPair,
68            ConcurrentMap<RegionAndName, KeyPair> credentialsMap,
69            @Named("SECURITY") Cache<RegionAndName, String> securityGroupMap,
70            Provider<RunInstancesOptions> optionsProvider) {
71      this.makeKeyPair = checkNotNull(makeKeyPair, "makeKeyPair");
72      this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
73      this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
74      this.optionsProvider = checkNotNull(optionsProvider, "optionsProvider");
75   }
76 
77   public RunInstancesOptions execute(String region, String group, Template template) {
78 
79      RunInstancesOptions instanceOptions = getOptionsProvider().get().asType(template.getHardware().getId());
80 
81      String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, template.getOptions());
82 
83      addSecurityGroups(region, group, template, instanceOptions);
84      if (template.getOptions() instanceof EC2TemplateOptions) {
85 
86         if (keyPairName != null)
87            instanceOptions.withKeyName(keyPairName);
88 
89         byte[] userData = EC2TemplateOptions.class.cast(template.getOptions()).getUserData();
90 
91         if (userData != null)
92            instanceOptions.withUserData(userData);
93 
94         Set<BlockDeviceMapping> blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions())
95                  .getBlockDeviceMappings();
96         if (blockDeviceMappings.size() > 0) {
97            checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")),
98                     "BlockDeviceMapping only available on ebs boot");
99            instanceOptions.withBlockDeviceMappings(blockDeviceMappings);
100         }
101      }
102      return instanceOptions;
103   }
104 
105   protected void addSecurityGroups(String region, String group, Template template, RunInstancesOptions instanceOptions) {
106      Set<String> groups = getSecurityGroupsForTagAndOptions(region, group, template.getOptions());
107      instanceOptions.withSecurityGroups(groups);
108   }
109 
110   @VisibleForTesting
111   public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String group, TemplateOptions options) {
112      String keyPairName = null;
113      boolean shouldAutomaticallyCreateKeyPair = true;
114 
115      if (options instanceof EC2TemplateOptions) {
116         keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair();
117         if (keyPairName == null)
118            shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options)
119                     .shouldAutomaticallyCreateKeyPair();
120      }
121 
122      if (keyPairName == null && shouldAutomaticallyCreateKeyPair) {
123         keyPairName = createOrImportKeyPair(region, group, options);
124      } else if (keyPairName != null) {
125         if (options.getOverridingCredentials() != null && options.getOverridingCredentials().credential != null) {
126            String pem = options.getOverridingCredentials().credential;
127            KeyPair keyPair = KeyPair.builder().region(region).keyName(keyPairName).fingerprint(
128                     fingerprintPrivateKey(pem)).sha1OfPrivateKey(sha1PrivateKey(pem)).keyMaterial(pem).build();
129            RegionAndName key = new RegionAndName(region, keyPairName);
130            credentialsMap.put(key, keyPair);
131         }
132      }
133 
134      if (options.getRunScript() != null) {
135         RegionAndName regionAndName = new RegionAndName(region, keyPairName);
136         checkArgument(
137                  credentialsMap.containsKey(regionAndName),
138                  "no private key configured for: %s; please use options.overrideLoginCredentialWith(rsa_private_text)",
139                  regionAndName);
140      }
141      return keyPairName;
142   }
143 
144   // base EC2 driver currently does not support key import
145   protected String createOrImportKeyPair(String region, String group, TemplateOptions options) {
146      RegionAndName regionAndGroup = new RegionAndName(region, group);
147      KeyPair keyPair;
148      // make sure that we don't request multiple keys simultaneously
149      synchronized (credentialsMap) {
150         // if there is already a keypair for the group specified, use it
151         if (credentialsMap.containsKey(regionAndGroup))
152            return credentialsMap.get(regionAndGroup).getKeyName();
153 
154         // otherwise create a new keypair and key it under the group and also the regular keyname
155         keyPair = makeKeyPair.apply(new RegionAndName(region, group));
156         credentialsMap.put(regionAndGroup, keyPair);
157      }
158      credentialsMap.put(new RegionAndName(region, keyPair.getKeyName()), keyPair);
159      return keyPair.getKeyName();
160   }
161 
162   @VisibleForTesting
163   public Set<String> getSecurityGroupsForTagAndOptions(String region, @Nullable String group, TemplateOptions options) {
164      Builder<String> groups = ImmutableSet.<String> builder();
165 
166      if (group != null) {
167         String markerGroup = String.format("jclouds#%s#%s", group, region);
168         groups.add(markerGroup);
169 
170         RegionNameAndIngressRules regionNameAndIngessRulesForMarkerGroup;
171 
172         if (userSpecifiedTheirOwnGroups(options)) {
173            regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, new int[] {},
174                     false);
175            groups.addAll(EC2TemplateOptions.class.cast(options).getGroups());
176         } else {
177            regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, options
178                     .getInboundPorts(), true);
179         }
180         // this will create if not yet exists.
181         securityGroupMap.getUnchecked(regionNameAndIngessRulesForMarkerGroup);
182      }
183      return groups.build();
184   }
185 
186   protected boolean userSpecifiedTheirOwnGroups(TemplateOptions options) {
187      return options instanceof EC2TemplateOptions && EC2TemplateOptions.class.cast(options).getGroups().size() > 0;
188   }
189 
190   // allows us to mock this method
191   @VisibleForTesting
192   public javax.inject.Provider<RunInstancesOptions> getOptionsProvider() {
193      return optionsProvider;
194   }
195}

[all classes][org.jclouds.ec2.compute.strategy]
EMMA 2.0.5312 (C) Vladimir Roubtsov