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

COVERAGE SUMMARY FOR SOURCE FILE [SoftLayerComputeServiceAdapter.java]

nameclass, %method, %block, %line, %
SoftLayerComputeServiceAdapter.java0%   (0/3)0%   (0/16)0%   (0/596)0%   (0/85)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SoftLayerComputeServiceAdapter0%   (0/1)0%   (0/12)0%   (0/508)0%   (0/71)
SoftLayerComputeServiceAdapter (SoftLayerClient, SoftLayerComputeServiceAdapt... 0%   (0/1)0%   (0/78)0%   (0/13)
createNodeWithGroupEncodedIntoNameThenStoreCredentials (String, String, Templ... 0%   (0/1)0%   (0/188)0%   (0/19)
destroyNode (String): void 0%   (0/1)0%   (0/48)0%   (0/8)
getNode (String): VirtualGuest 0%   (0/1)0%   (0/9)0%   (0/2)
getPrices (Template): Iterable 0%   (0/1)0%   (0/72)0%   (0/12)
listHardwareProfiles (): Iterable 0%   (0/1)0%   (0/67)0%   (0/8)
listImages (): Iterable 0%   (0/1)0%   (0/9)0%   (0/1)
listLocations (): Iterable 0%   (0/1)0%   (0/6)0%   (0/1)
listNodes (): Iterable 0%   (0/1)0%   (0/10)0%   (0/1)
rebootNode (String): void 0%   (0/1)0%   (0/7)0%   (0/2)
resumeNode (String): void 0%   (0/1)0%   (0/7)0%   (0/2)
suspendNode (String): void 0%   (0/1)0%   (0/7)0%   (0/2)
     
class SoftLayerComputeServiceAdapter$10%   (0/1)0%   (0/2)0%   (0/31)0%   (0/6)
SoftLayerComputeServiceAdapter$1 (SoftLayerComputeServiceAdapter): void 0%   (0/1)0%   (0/6)0%   (0/1)
apply (VirtualGuest): boolean 0%   (0/1)0%   (0/25)0%   (0/5)
     
class SoftLayerComputeServiceAdapter$VirtualGuestHasLoginDetailsPresent0%   (0/1)0%   (0/2)0%   (0/57)0%   (0/9)
SoftLayerComputeServiceAdapter$VirtualGuestHasLoginDetailsPresent (SoftLayerC... 0%   (0/1)0%   (0/9)0%   (0/3)
apply (VirtualGuest): boolean 0%   (0/1)0%   (0/48)0%   (0/6)

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.softlayer.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 com.google.common.base.Predicates.and;
25import static com.google.common.collect.Iterables.filter;
26import static com.google.common.collect.Iterables.find;
27import static com.google.common.collect.Iterables.get;
28import static org.jclouds.softlayer.predicates.ProductItemPredicates.capacity;
29import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
30import static org.jclouds.softlayer.predicates.ProductItemPredicates.matches;
31import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX;
32import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE;
33import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY;
34import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED;
35 
36import java.util.Map;
37import java.util.Set;
38import java.util.regex.Pattern;
39 
40import javax.annotation.Resource;
41import javax.inject.Inject;
42import javax.inject.Named;
43import javax.inject.Singleton;
44 
45import org.jclouds.collect.Memoized;
46import org.jclouds.compute.ComputeService;
47import org.jclouds.compute.ComputeServiceAdapter;
48import org.jclouds.compute.domain.Template;
49import org.jclouds.compute.reference.ComputeServiceConstants;
50import org.jclouds.domain.Credentials;
51import org.jclouds.logging.Logger;
52import org.jclouds.predicates.RetryablePredicate;
53import org.jclouds.softlayer.SoftLayerClient;
54import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
55import org.jclouds.softlayer.domain.Datacenter;
56import org.jclouds.softlayer.domain.Password;
57import org.jclouds.softlayer.domain.ProductItem;
58import org.jclouds.softlayer.domain.ProductItemPrice;
59import org.jclouds.softlayer.domain.ProductOrder;
60import org.jclouds.softlayer.domain.ProductOrderReceipt;
61import org.jclouds.softlayer.domain.ProductPackage;
62import org.jclouds.softlayer.domain.VirtualGuest;
63 
64import com.google.common.base.Predicate;
65import com.google.common.base.Splitter;
66import com.google.common.base.Supplier;
67import com.google.common.collect.ImmutableSet;
68import com.google.common.collect.Iterables;
69import com.google.common.collect.ImmutableSet.Builder;
70 
71/**
72 * defines the connection between the {@link SoftLayerClient} implementation and the jclouds
73 * {@link ComputeService}
74 * 
75 */
76@Singleton
77public class SoftLayerComputeServiceAdapter implements
78         ComputeServiceAdapter<VirtualGuest, Iterable<ProductItem>, ProductItem, Datacenter> {
79 
80   @Resource
81   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
82   protected Logger logger = Logger.NULL;
83 
84   private final SoftLayerClient client;
85   private final Supplier<ProductPackage> productPackageSupplier;
86   private final RetryablePredicate<VirtualGuest> loginDetailsTester;
87   private final long guestLoginDelay;
88   private final Pattern cpuPattern;
89   private final Pattern disk0Type;
90   private final float portSpeed;
91   private final Iterable<ProductItemPrice> prices;
92 
93   @Inject
94   public SoftLayerComputeServiceAdapter(SoftLayerClient client,
95            VirtualGuestHasLoginDetailsPresent virtualGuestHasLoginDetailsPresent,
96            @Memoized Supplier<ProductPackage> productPackageSupplier, Iterable<ProductItemPrice> prices,
97            @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX) String cpuRegex,
98            @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE) String disk0Type,
99            @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED) float portSpeed,
100            @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY) long guestLoginDelay) {
101      this.client = checkNotNull(client, "client");
102      this.guestLoginDelay = guestLoginDelay;
103      this.productPackageSupplier = checkNotNull(productPackageSupplier, "productPackageSupplier");
104      checkArgument(guestLoginDelay > 500, "guestOrderDelay must be in milliseconds and greater than 500");
105      this.loginDetailsTester = new RetryablePredicate<VirtualGuest>(virtualGuestHasLoginDetailsPresent,
106               guestLoginDelay);
107      this.cpuPattern = Pattern.compile(checkNotNull(cpuRegex, "cpuRegex"));
108      this.prices = checkNotNull(prices, "prices");
109      this.portSpeed = portSpeed;
110      checkArgument(portSpeed > 0, "portSpeed must be greater than zero, often 10, 100, 1000, 10000");
111      this.disk0Type = Pattern.compile(".*" + checkNotNull(disk0Type, "disk0Type") + ".*");
112   }
113 
114   @Override
115   public VirtualGuest createNodeWithGroupEncodedIntoNameThenStoreCredentials(String group, String name,
116            Template template, Map<String, Credentials> credentialStore) {
117      checkNotNull(template, "template was null");
118      checkNotNull(template.getOptions(), "template options was null");
119      checkArgument(template.getOptions().getClass().isAssignableFrom(SoftLayerTemplateOptions.class),
120               "options class %s should have been assignable from SoftLayerTemplateOptions", template.getOptions()
121                        .getClass());
122 
123      String domainName = template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName();
124 
125      VirtualGuest newGuest = VirtualGuest.builder().domain(domainName).hostname(name).build();
126 
127      ProductOrder order = ProductOrder.builder().packageId(productPackageSupplier.get().getId()).location(
128               template.getLocation().getId()).quantity(1).useHourlyPricing(true).prices(getPrices(template))
129               .virtualGuest(newGuest).build();
130 
131      logger.debug(">> ordering new virtualGuest domain(%s) hostname(%s)", domainName, name);
132      ProductOrderReceipt productOrderReceipt = client.getVirtualGuestClient().orderVirtualGuest(order);
133      VirtualGuest result = get(productOrderReceipt.getOrderDetails().getVirtualGuests(), 0);
134      logger.trace("<< virtualGuest(%s)", result.getId());
135 
136      logger.debug(">> awaiting login details for virtualGuest(%s)", result.getId());
137      boolean orderInSystem = loginDetailsTester.apply(result);
138      logger.trace("<< virtualGuest(%s) complete(%s)", result.getId(), orderInSystem);
139 
140      checkState(orderInSystem, "order for guest %s doesn't have login details within %sms", result, Long
141               .toString(guestLoginDelay));
142      result = client.getVirtualGuestClient().getVirtualGuest(result.getId());
143 
144      Password pw = get(result.getOperatingSystem().getPasswords(), 0);
145      Credentials credentials = new Credentials(pw.getUsername(), pw.getPassword());
146      credentialStore.put("node#" + result.getId(), credentials);
147      return result;
148   }
149 
150   private Iterable<ProductItemPrice> getPrices(Template template) {
151      Builder<ProductItemPrice> result = ImmutableSet.<ProductItemPrice> builder();
152 
153      int imageId = Integer.parseInt(template.getImage().getId());
154      result.add(ProductItemPrice.builder().id(imageId).build());
155 
156      Iterable<String> hardwareIds = Splitter.on(",").split(template.getHardware().getId());
157      for (String hardwareId : hardwareIds) {
158         int id = Integer.parseInt(hardwareId);
159         result.add(ProductItemPrice.builder().id(id).build());
160      }
161      ProductItem uplinkItem = find(productPackageSupplier.get().getItems(), and(capacity(portSpeed),
162               categoryCode("port_speed")));
163      result.add(get(uplinkItem.getPrices(), 0));
164      result.addAll(prices);
165      return result.build();
166   }
167 
168   @Override
169   public Iterable<Iterable<ProductItem>> listHardwareProfiles() {
170      ProductPackage productPackage = productPackageSupplier.get();
171      Set<ProductItem> items = productPackage.getItems();
172      Builder<Iterable<ProductItem>> result = ImmutableSet.<Iterable<ProductItem>> builder();
173      for (ProductItem cpuItem : filter(items, matches(cpuPattern))) {
174         for (ProductItem ramItem : filter(items, categoryCode("ram"))) {
175            for (ProductItem sanItem : filter(items, and(matches(disk0Type), categoryCode("guest_disk0")))) {
176               result.add(ImmutableSet.of(cpuItem, ramItem, sanItem));
177            }
178         }
179      }
180      return result.build();
181   }
182 
183   @Override
184   public Iterable<ProductItem> listImages() {
185      return filter(productPackageSupplier.get().getItems(), categoryCode("os"));
186   }
187 
188   @Override
189   public Iterable<VirtualGuest> listNodes() {
190      return Iterables.filter(client.getVirtualGuestClient().listVirtualGuests(), new Predicate<VirtualGuest>(){
191 
192         @Override
193         public boolean apply(VirtualGuest arg0) {
194            boolean hasBillingItem = arg0.getBillingItemId() != -1;
195            if (hasBillingItem)
196               return true;
197            logger.trace("guest invalid, as it has no billing item %s", arg0);
198            return false;
199         }
200         
201      });
202   }
203 
204   @Override
205   public Iterable<Datacenter> listLocations() {
206      return productPackageSupplier.get().getDatacenters();
207   }
208 
209   @Override
210   public VirtualGuest getNode(String id) {
211      long serverId = Long.parseLong(id);
212      return client.getVirtualGuestClient().getVirtualGuest(serverId);
213   }
214 
215   @Override
216   public void destroyNode(String id) {
217      VirtualGuest guest = getNode(id);
218      if (guest == null)
219         return;
220 
221      if (guest.getBillingItemId() == -1)
222         throw new IllegalStateException(String.format("no billing item for guest(%s) so we cannot cancel the order",
223                  id));
224 
225      logger.debug(">> canceling service for guest(%s) billingItem(%s)", id, guest.getBillingItemId());
226      client.getVirtualGuestClient().cancelService(guest.getBillingItemId());
227   }
228 
229   @Override
230   public void rebootNode(String id) {
231      client.getVirtualGuestClient().rebootHardVirtualGuest(Long.parseLong(id));
232   }
233 
234   @Override
235   public void resumeNode(String id) {
236      client.getVirtualGuestClient().resumeVirtualGuest(Long.parseLong(id));
237   }
238 
239   @Override
240   public void suspendNode(String id) {
241      client.getVirtualGuestClient().pauseVirtualGuest(Long.parseLong(id));
242   }
243 
244   public static class VirtualGuestHasLoginDetailsPresent implements Predicate<VirtualGuest> {
245      private final SoftLayerClient client;
246 
247      @Inject
248      public VirtualGuestHasLoginDetailsPresent(SoftLayerClient client) {
249         this.client = checkNotNull(client, "client was null");
250      }
251 
252      @Override
253      public boolean apply(VirtualGuest guest) {
254         checkNotNull(guest, "virtual guest was null");
255 
256         VirtualGuest newGuest = client.getVirtualGuestClient().getVirtualGuest(guest.getId());
257         boolean hasBackendIp = newGuest.getPrimaryBackendIpAddress() != null;
258         boolean hasPrimaryIp = newGuest.getPrimaryIpAddress() != null;
259         boolean hasPasswords = newGuest.getOperatingSystem() != null
260                  && newGuest.getOperatingSystem().getPasswords().size() > 0;
261 
262         return hasBackendIp && hasPrimaryIp && hasPasswords;
263      }
264   }
265}

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