EMMA Coverage Report (generated Wed Jun 22 19:47:49 EDT 2011)
[all classes][org.jclouds.ec2.compute.strategy]

COVERAGE SUMMARY FOR SOURCE FILE [EC2CreateNodesInGroupThenAddToSet.java]

nameclass, %method, %block, %line, %
EC2CreateNodesInGroupThenAddToSet.java100% (2/2)100% (8/8)84%  (261/311)95%  (44.5/47)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class EC2CreateNodesInGroupThenAddToSet100% (1/1)100% (6/6)83%  (250/300)95%  (43.5/46)
createNodesInRegionAndZone (String, String, int, Template, RunInstancesOption... 100% (1/1)49%  (47/96)82%  (9/11)
populateCredentials (Iterable): void 100% (1/1)98%  (54/55)94%  (8.5/9)
<static initializer> 100% (1/1)100% (5/5)100% (1/1)
EC2CreateNodesInGroupThenAddToSet (EC2Client, Provider, CreateKeyPairAndSecur... 100% (1/1)100% (54/54)100% (11/11)
createKeyPairAndSecurityGroupsAsNeededThenRunInstances (String, int, Template... 100% (1/1)100% (23/23)100% (4/4)
execute (String, int, Template, Set, Map, Multimap): Map 100% (1/1)100% (67/67)100% (10/10)
     
class EC2CreateNodesInGroupThenAddToSet$1100% (1/1)100% (2/2)100% (11/11)100% (2/2)
EC2CreateNodesInGroupThenAddToSet$1 (): void 100% (1/1)100% (3/3)100% (1/1)
apply (RunningInstance): RegionAndName 100% (1/1)100% (8/8)100% (1/1)

1/**
2 *
3 * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4 *
5 * ====================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * 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, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 * ====================================================================
18 */
19package org.jclouds.ec2.compute.strategy;
20 
21import static com.google.common.base.Preconditions.checkNotNull;
22import static com.google.common.collect.Iterables.all;
23import static com.google.common.collect.Iterables.transform;
24import static org.jclouds.ec2.compute.util.EC2ComputeUtils.getZoneFromLocationOrNull;
25 
26import java.util.Map;
27import java.util.Set;
28import java.util.concurrent.Future;
29 
30import javax.annotation.Resource;
31import javax.inject.Inject;
32import javax.inject.Named;
33import javax.inject.Provider;
34import javax.inject.Singleton;
35 
36import org.jclouds.aws.util.AWSUtils;
37import org.jclouds.compute.config.CustomizationResponse;
38import org.jclouds.compute.domain.NodeMetadata;
39import org.jclouds.compute.domain.Template;
40import org.jclouds.compute.domain.TemplateBuilder;
41import org.jclouds.compute.reference.ComputeServiceConstants;
42import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
43import org.jclouds.compute.util.ComputeUtils;
44import org.jclouds.domain.Credentials;
45import org.jclouds.ec2.EC2Client;
46import org.jclouds.ec2.compute.domain.RegionAndName;
47import org.jclouds.ec2.compute.predicates.InstancePresent;
48import org.jclouds.ec2.domain.RunningInstance;
49import org.jclouds.ec2.options.RunInstancesOptions;
50import org.jclouds.logging.Logger;
51 
52import com.google.common.annotations.VisibleForTesting;
53import com.google.common.base.Function;
54import com.google.common.base.Joiner;
55import com.google.common.collect.ImmutableSet;
56import com.google.common.collect.Iterables;
57import com.google.common.collect.Multimap;
58 
59/**
60 * creates futures that correlate to
61 * 
62 * @author Adrian Cole
63 */
64@Singleton
65public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThenAddToSet {
66 
67   @Resource
68   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
69   protected Logger logger = Logger.NULL;
70 
71   @VisibleForTesting
72   final EC2Client client;
73   @VisibleForTesting
74   final CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize;
75   @VisibleForTesting
76   final Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata;
77   @VisibleForTesting
78   final ComputeUtils utils;
79   final InstancePresent instancePresent;
80   final Function<RunningInstance, Credentials> instanceToCredentials;
81   final Map<String, Credentials> credentialStore;
82   final Provider<TemplateBuilder> templateBuilderProvider;
83 
84   @Inject
85   protected EC2CreateNodesInGroupThenAddToSet(
86            EC2Client client,
87            Provider<TemplateBuilder> templateBuilderProvider,
88            CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
89            InstancePresent instancePresent, Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
90            Function<RunningInstance, Credentials> instanceToCredentials, Map<String, Credentials> credentialStore,
91            ComputeUtils utils) {
92      this.client = checkNotNull(client, "client");
93      this.templateBuilderProvider = checkNotNull(templateBuilderProvider, "templateBuilderProvider");
94      this.instancePresent = checkNotNull(instancePresent, "instancePresent");
95      this.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = checkNotNull(
96               createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
97               "createKeyPairAndSecurityGroupsAsNeededAndReturncustomize");
98      this.runningInstanceToNodeMetadata = checkNotNull(runningInstanceToNodeMetadata, "runningInstanceToNodeMetadata");
99      this.instanceToCredentials = checkNotNull(instanceToCredentials, "instanceToCredentials");
100      this.credentialStore = checkNotNull(credentialStore, "credentialStore");
101      this.utils = checkNotNull(utils, "utils");
102   }
103 
104   public static Function<RunningInstance, RegionAndName> instanceToRegionAndName = new Function<RunningInstance, RegionAndName>() {
105      @Override
106      public RegionAndName apply(RunningInstance from) {
107         return new RegionAndName(from.getRegion(), from.getId());
108      }
109   };
110 
111   @Override
112   public Map<?, Future<Void>> execute(String group, int count, Template template, Set<NodeMetadata> goodNodes,
113            Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
114      // ensure we don't mutate the input template
115      template = templateBuilderProvider.get().fromTemplate(template).build();
116      Iterable<? extends RunningInstance> started = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(group,
117               count, template);
118 
119      Iterable<RegionAndName> ids = transform(started, instanceToRegionAndName);
120 
121      String idsString = Joiner.on(',').join(ids);
122      if (Iterables.size(ids) > 0) {
123         logger.debug("<< started instances(%s)", idsString);
124         all(ids, instancePresent);
125         logger.debug("<< present instances(%s)", idsString);
126         populateCredentials(started);
127      }
128 
129      return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(), transform(started,
130               runningInstanceToNodeMetadata), goodNodes, badNodes, customizationResponses);
131   }
132 
133   protected void populateCredentials(Iterable<? extends RunningInstance> started) {
134      Credentials credentials = null;
135      for (RunningInstance instance : started) {
136         credentials = instanceToCredentials.apply(instance);
137         if (credentials != null)
138            break;
139      }
140      if (credentials != null)
141         for (RunningInstance instance : started)
142            credentialStore.put("node#" + instance.getRegion() + "/" + instance.getId(), credentials);
143   }
144 
145   // TODO write test for this
146   protected Iterable<? extends RunningInstance> createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String group,
147            int count, Template template) {
148      String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation());
149      String zone = getZoneFromLocationOrNull(template.getLocation());
150      RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region,
151               group, template);
152      return createNodesInRegionAndZone(region, zone, count, template, instanceOptions);
153   }
154 
155   protected Iterable<? extends RunningInstance> createNodesInRegionAndZone(String region, String zone, int count,
156            Template template, RunInstancesOptions instanceOptions) {
157      int countStarted = 0;
158      int tries = 0;
159      Iterable<? extends RunningInstance> started = ImmutableSet.<RunningInstance> of();
160 
161      while (countStarted < count && tries++ < count) {
162         if (logger.isDebugEnabled())
163            logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count - countStarted, region,
164                     zone, template.getImage().getProviderId(), instanceOptions.buildFormParameters());
165 
166         started = Iterables.concat(started, client.getInstanceServices().runInstancesInRegion(region, zone,
167                  template.getImage().getProviderId(), 1, count - countStarted, instanceOptions));
168 
169         countStarted = Iterables.size(started);
170         if (countStarted < count)
171            logger.debug(">> not enough instances (%d/%d) started, attempting again", countStarted, count);
172      }
173      return started;
174   }
175 
176}

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