EMMA Coverage Report (generated Fri Apr 27 15:03:37 EDT 2012)
[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%  (292/346)87%  (55/63)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions100% (1/1)88%  (7/8)84%  (292/346)87%  (55/63)
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% (30/30)100% (7/7)
addSecurityGroups (String, String, Template, RunInstancesOptions): void 100% (1/1)100% (12/12)100% (3/3)
createNewKeyPairUnlessUserSpecifiedOtherwise (String, String, TemplateOptions... 100% (1/1)100% (90/90)100% (18/18)
getSecurityGroupsForTagAndOptions (String, String, TemplateOptions): Set 100% (1/1)100% (64/64)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.compute.config.ComputeServiceProperties.RESOURCENAME_DELIMITER;
25import static org.jclouds.crypto.SshKeys.fingerprintPrivateKey;
26import static org.jclouds.crypto.SshKeys.sha1PrivateKey;
27 
28import java.util.Set;
29import java.util.concurrent.ConcurrentMap;
30 
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.LoadingCache;
48import com.google.common.collect.ImmutableSet;
49import com.google.common.collect.ImmutableSet.Builder;
50import com.google.inject.Inject;
51 
52/**
53 * 
54 * @author Adrian Cole
55 */
56@Singleton
57public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions {
58   @VisibleForTesting
59   public Function<RegionAndName, KeyPair> makeKeyPair;
60   @VisibleForTesting
61   public final ConcurrentMap<RegionAndName, KeyPair> credentialsMap;
62   @VisibleForTesting
63   public final LoadingCache<RegionAndName, String> securityGroupMap;
64   @VisibleForTesting
65   public final Provider<RunInstancesOptions> optionsProvider;
66 
67   @Inject
68   public CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(Function<RegionAndName, KeyPair> makeKeyPair,
69            ConcurrentMap<RegionAndName, KeyPair> credentialsMap,
70            @Named("SECURITY") LoadingCache<RegionAndName, String> securityGroupMap,
71            Provider<RunInstancesOptions> optionsProvider) {
72      this.makeKeyPair = checkNotNull(makeKeyPair, "makeKeyPair");
73      this.credentialsMap = checkNotNull(credentialsMap, "credentialsMap");
74      this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
75      this.optionsProvider = checkNotNull(optionsProvider, "optionsProvider");
76   }
77 
78   public RunInstancesOptions execute(String region, String group, Template template) {
79 
80      RunInstancesOptions instanceOptions = getOptionsProvider().get().asType(template.getHardware().getId());
81 
82      String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, group, template.getOptions());
83 
84      addSecurityGroups(region, group, template, instanceOptions);
85      if (template.getOptions() instanceof EC2TemplateOptions) {
86 
87         if (keyPairName != null)
88            instanceOptions.withKeyName(keyPairName);
89 
90         byte[] userData = EC2TemplateOptions.class.cast(template.getOptions()).getUserData();
91 
92         if (userData != null)
93            instanceOptions.withUserData(userData);
94 
95         Set<BlockDeviceMapping> blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions())
96                  .getBlockDeviceMappings();
97         if (blockDeviceMappings.size() > 0) {
98            checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")),
99                     "BlockDeviceMapping only available on ebs boot");
100            instanceOptions.withBlockDeviceMappings(blockDeviceMappings);
101         }
102      }
103      return instanceOptions;
104   }
105 
106   protected void addSecurityGroups(String region, String group, Template template, RunInstancesOptions instanceOptions) {
107      Set<String> groups = getSecurityGroupsForTagAndOptions(region, group, template.getOptions());
108      instanceOptions.withSecurityGroups(groups);
109   }
110 
111   @VisibleForTesting
112   public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String group, TemplateOptions options) {
113      String keyPairName = null;
114      boolean shouldAutomaticallyCreateKeyPair = true;
115 
116      if (options instanceof EC2TemplateOptions) {
117         keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair();
118         if (keyPairName == null)
119            shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options)
120                     .shouldAutomaticallyCreateKeyPair();
121      }
122 
123      if (keyPairName == null && shouldAutomaticallyCreateKeyPair) {
124         keyPairName = createOrImportKeyPair(region, group, options);
125      } else if (keyPairName != null) {
126         if (options.getLoginPrivateKey() != null) {
127            String pem = options.getLoginPrivateKey();
128            KeyPair keyPair = KeyPair.builder().region(region).keyName(keyPairName).fingerprint(
129                     fingerprintPrivateKey(pem)).sha1OfPrivateKey(sha1PrivateKey(pem)).keyMaterial(pem).build();
130            RegionAndName key = new RegionAndName(region, keyPairName);
131            credentialsMap.put(key, keyPair);
132         }
133      }
134 
135      if (options.getRunScript() != null) {
136         RegionAndName regionAndName = new RegionAndName(region, keyPairName);
137         checkArgument(
138                  credentialsMap.containsKey(regionAndName),
139                  "no private key configured for: %s; please use options.overrideLoginCredentialWith(rsa_private_text)",
140                  regionAndName);
141      }
142      return keyPairName;
143   }
144 
145   // base EC2 driver currently does not support key import
146   protected String createOrImportKeyPair(String region, String group, TemplateOptions options) {
147      RegionAndName regionAndGroup = new RegionAndName(region, group);
148      KeyPair keyPair;
149      // make sure that we don't request multiple keys simultaneously
150      synchronized (credentialsMap) {
151         // if there is already a keypair for the group specified, use it
152         if (credentialsMap.containsKey(regionAndGroup))
153            return credentialsMap.get(regionAndGroup).getKeyName();
154 
155         // otherwise create a new keypair and key it under the group and also the regular keyname
156         keyPair = makeKeyPair.apply(new RegionAndName(region, group));
157         credentialsMap.put(regionAndGroup, keyPair);
158      }
159      credentialsMap.put(new RegionAndName(region, keyPair.getKeyName()), keyPair);
160      return keyPair.getKeyName();
161   }
162 
163   @Inject(optional = true)
164   @Named(RESOURCENAME_DELIMITER)
165   char delimiter = '#';
166 
167   @VisibleForTesting
168   public Set<String> getSecurityGroupsForTagAndOptions(String region, @Nullable String group, TemplateOptions options) {
169      Builder<String> groups = ImmutableSet.builder();
170 
171      if (group != null) {
172         String markerGroup = String.format("jclouds#%s#%s", group, region).replace('#', delimiter);
173         groups.add(markerGroup);
174 
175         RegionNameAndIngressRules regionNameAndIngessRulesForMarkerGroup;
176 
177         if (userSpecifiedTheirOwnGroups(options)) {
178            regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, new int[] {},
179                     false);
180            groups.addAll(EC2TemplateOptions.class.cast(options).getGroups());
181         } else {
182            regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, options
183                     .getInboundPorts(), true);
184         }
185         // this will create if not yet exists.
186         securityGroupMap.getUnchecked(regionNameAndIngessRulesForMarkerGroup);
187      }
188      return groups.build();
189   }
190 
191   protected boolean userSpecifiedTheirOwnGroups(TemplateOptions options) {
192      return options instanceof EC2TemplateOptions && EC2TemplateOptions.class.cast(options).getGroups().size() > 0;
193   }
194 
195   // allows us to mock this method
196   @VisibleForTesting
197   public javax.inject.Provider<RunInstancesOptions> getOptionsProvider() {
198      return optionsProvider;
199   }
200}

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