mirror of https://github.com/apache/jclouds.git
Merge branch 'master' of git://github.com/jclouds/jclouds
This commit is contained in:
commit
9e6d52c54b
|
@ -39,6 +39,7 @@ public class SoftLayerPropertiesBuilder extends PropertiesBuilder {
|
|||
properties.setProperty(PROPERTY_ENDPOINT, "https://api.softlayer.com/rest");
|
||||
properties.setProperty(PROPERTY_API_VERSION, "3");
|
||||
properties.setProperty(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME, "Cloud Server");
|
||||
properties.setProperty(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_ORDER_DELAY, "5000");
|
||||
properties.setProperty(PROPERTY_ISO3166_CODES, "SG,US-CA,US-TX,US-VA,US-WA,US-TX");
|
||||
return properties;
|
||||
}
|
||||
|
|
|
@ -18,20 +18,12 @@
|
|||
*/
|
||||
package org.jclouds.softlayer.compute.strategy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.matches;
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
|
||||
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
|
@ -39,25 +31,21 @@ import org.jclouds.domain.Credentials;
|
|||
import org.jclouds.softlayer.SoftLayerClient;
|
||||
import org.jclouds.softlayer.compute.functions.ProductItems;
|
||||
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
||||
import org.jclouds.softlayer.domain.BillingItemVirtualGuest;
|
||||
import org.jclouds.softlayer.domain.Datacenter;
|
||||
import org.jclouds.softlayer.domain.OperatingSystem;
|
||||
import org.jclouds.softlayer.domain.Password;
|
||||
import org.jclouds.softlayer.domain.ProductItem;
|
||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||
import org.jclouds.softlayer.domain.ProductOrder;
|
||||
import org.jclouds.softlayer.domain.ProductPackage;
|
||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||
import org.jclouds.softlayer.domain.*;
|
||||
import org.jclouds.softlayer.features.AccountClient;
|
||||
import org.jclouds.softlayer.features.ProductPackageClient;
|
||||
import org.jclouds.softlayer.reference.SoftLayerConstants;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
||||
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||
|
||||
/**
|
||||
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds
|
||||
|
@ -66,9 +54,9 @@ import com.google.common.collect.Sets;
|
|||
*/
|
||||
@Singleton
|
||||
public class SoftLayerComputeServiceAdapter implements
|
||||
ComputeServiceAdapter<VirtualGuest, Set<ProductItem>, ProductItem, Datacenter> {
|
||||
ComputeServiceAdapter<VirtualGuest, Set<ProductItem>, ProductItem, Datacenter> {
|
||||
|
||||
public static final String SAN_DESCRIPTION_REGEX=".*GB \\(SAN\\).*";
|
||||
public static final String SAN_DESCRIPTION_REGEX = ".*GB \\(SAN\\).*";
|
||||
private static final Float BOOT_VOLUME_CAPACITY = 100F;
|
||||
|
||||
private final SoftLayerClient client;
|
||||
|
@ -87,62 +75,36 @@ public class SoftLayerComputeServiceAdapter implements
|
|||
checkNotNull(template, "template was null");
|
||||
checkNotNull(template.getOptions(), "template options was null");
|
||||
checkArgument(template.getOptions().getClass().isAssignableFrom(SoftLayerTemplateOptions.class),
|
||||
"options class %s should have been assignable from SoftLayerTemplateOptions", template.getOptions()
|
||||
.getClass());
|
||||
"options class %s should have been assignable from SoftLayerTemplateOptions", template.getOptions()
|
||||
.getClass());
|
||||
|
||||
Iterable<VirtualGuest> existing = findVirtualGuests(name,group);
|
||||
if(!Iterables.isEmpty(existing)) {
|
||||
throw new IllegalStateException(
|
||||
"VirtualGuest(s) already exist with hostname:"+name+", group:"+group+". Existing:"+existing);
|
||||
}
|
||||
String domainName = template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName();
|
||||
|
||||
VirtualGuest newGuest = VirtualGuest.builder()
|
||||
.domain(template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName())
|
||||
.hostname(name)
|
||||
.build();
|
||||
VirtualGuest newGuest = VirtualGuest.builder().domain(domainName).hostname(name).build();
|
||||
|
||||
ProductOrder order = ProductOrder.builder()
|
||||
.packageId(getProductPackage().getId())
|
||||
.location(template.getLocation().getId())
|
||||
.quantity(1)
|
||||
.useHourlyPricing(true)
|
||||
.prices(getPrices(template))
|
||||
.virtualGuest(newGuest)
|
||||
.build();
|
||||
ProductOrder order = ProductOrder.builder().packageId(getProductPackage().getId()).location(
|
||||
template.getLocation().getId()).quantity(1).useHourlyPricing(true).prices(getPrices(template))
|
||||
.virtualGuest(newGuest).build();
|
||||
|
||||
client.getVirtualGuestClient().orderVirtualGuest(order);
|
||||
ProductOrderReceipt productOrderReceipt = client.getVirtualGuestClient().orderVirtualGuest(order);
|
||||
VirtualGuest result = Iterables.get(productOrderReceipt.getOrderDetails().getVirtualGuests(), 0);
|
||||
|
||||
|
||||
VirtualGuest result = Iterables.getOnlyElement(findVirtualGuests(name, group));
|
||||
Credentials credentials = new Credentials(null,null);
|
||||
Credentials credentials = new Credentials(null, null);
|
||||
|
||||
// This information is not always available.
|
||||
OperatingSystem os = result.getOperatingSystem();
|
||||
if(os!=null) {
|
||||
if (os != null) {
|
||||
Set<Password> passwords = os.getPasswords();
|
||||
if(passwords.size()>0) {
|
||||
Password pw = Iterables.get(passwords,0);
|
||||
credentials = new Credentials(pw.getUsername(),pw.getPassword());
|
||||
if (passwords.size() > 0) {
|
||||
Password pw = Iterables.get(passwords, 0);
|
||||
credentials = new Credentials(pw.getUsername(), pw.getPassword());
|
||||
}
|
||||
}
|
||||
credentialStore.put("node#"+result.getId(),credentials);
|
||||
credentialStore.put("node#" + result.getId(), credentials);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Iterable<VirtualGuest> findVirtualGuests(String hostname,String domain) {
|
||||
checkNotNull(hostname,"hostname");
|
||||
checkNotNull(domain,"domain");
|
||||
|
||||
Set<VirtualGuest> result = Sets.newLinkedHashSet();
|
||||
|
||||
for( VirtualGuest guest : client.getVirtualGuestClient().listVirtualGuests()) {
|
||||
if ( guest.getHostname().equals(hostname) && guest.getDomain().equals(domain)) {
|
||||
result.add(guest);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Iterable<ProductItemPrice> getPrices(Template template) {
|
||||
Set<ProductItemPrice> result = Sets.newLinkedHashSet();
|
||||
|
@ -151,7 +113,7 @@ public class SoftLayerComputeServiceAdapter implements
|
|||
result.add(ProductItemPrice.builder().id(imageId).build());
|
||||
|
||||
Iterable<String> hardwareIds = Splitter.on(",").split(template.getHardware().getId());
|
||||
for(String hardwareId: hardwareIds) {
|
||||
for (String hardwareId : hardwareIds) {
|
||||
int id = Integer.parseInt(hardwareId);
|
||||
result.add(ProductItemPrice.builder().id(id).build());
|
||||
}
|
||||
|
@ -161,32 +123,32 @@ public class SoftLayerComputeServiceAdapter implements
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Iterable<Set<ProductItem>> listHardwareProfiles() {
|
||||
ProductPackage productPackage = getProductPackage();
|
||||
Set<ProductItem> items = productPackage.getItems();
|
||||
|
||||
Iterable<ProductItem> cpuItems = Iterables.filter(items, units("PRIVATE_CORE"));
|
||||
Iterable<ProductItem> ramItems = Iterables.filter(items,categoryCode("ram"));
|
||||
Iterable<ProductItem> sanItems = Iterables.filter(items, Predicates.and(matches(SAN_DESCRIPTION_REGEX),categoryCode("one_time_charge")));
|
||||
Iterable<ProductItem> ramItems = Iterables.filter(items, categoryCode("ram"));
|
||||
Iterable<ProductItem> sanItems = Iterables.filter(items, Predicates.and(matches(SAN_DESCRIPTION_REGEX),
|
||||
categoryCode("one_time_charge")));
|
||||
|
||||
Map<Float, ProductItem> cpuMap = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
|
||||
Map<Float, ProductItem> ramMap = Maps.uniqueIndex(ramItems, ProductItems.capacity());
|
||||
Map<Float, ProductItem> sanMap = Maps.uniqueIndex(sanItems, ProductItems.capacity());
|
||||
|
||||
final ProductItem bootVolume = sanMap.get(BOOT_VOLUME_CAPACITY);
|
||||
assert bootVolume!=null : "Boot volume capacity not found:"+BOOT_VOLUME_CAPACITY+", available:"+sanItems;
|
||||
assert bootVolume != null : "Boot volume capacity not found:" + BOOT_VOLUME_CAPACITY + ", available:" + sanItems;
|
||||
|
||||
Set<Set<ProductItem>> result = Sets.newLinkedHashSet();
|
||||
for(Map.Entry<Float, ProductItem> coresEntry : cpuMap.entrySet()) {
|
||||
for (Map.Entry<Float, ProductItem> coresEntry : cpuMap.entrySet()) {
|
||||
Float cores = coresEntry.getKey();
|
||||
ProductItem ramItem = ramMap.get(cores);
|
||||
//Amount of RAM and number of cores must match.
|
||||
if(ramItem==null) continue;
|
||||
// Amount of RAM and number of cores must match.
|
||||
if (ramItem == null)
|
||||
continue;
|
||||
|
||||
result.add(ImmutableSet.of(coresEntry.getValue(),ramItem,bootVolume));
|
||||
result.add(ImmutableSet.of(coresEntry.getValue(), ramItem, bootVolume));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -211,7 +173,7 @@ public class SoftLayerComputeServiceAdapter implements
|
|||
AccountClient accountClient = client.getAccountClient();
|
||||
ProductPackageClient productPackageClient = client.getProductPackageClient();
|
||||
|
||||
ProductPackage p = Iterables.find(accountClient.getActivePackages(),named(virtualGuestPackageName));
|
||||
ProductPackage p = Iterables.find(accountClient.getActivePackages(), named(virtualGuestPackageName));
|
||||
return productPackageClient.getProductPackage(p.getId());
|
||||
}
|
||||
|
||||
|
@ -224,10 +186,12 @@ public class SoftLayerComputeServiceAdapter implements
|
|||
@Override
|
||||
public void destroyNode(String id) {
|
||||
VirtualGuest guest = getNode(id);
|
||||
if(guest==null) return;
|
||||
if (guest == null)
|
||||
return;
|
||||
|
||||
BillingItemVirtualGuest billingItem = guest.getBillingItem();
|
||||
if (billingItem==null) return;
|
||||
if (billingItem == null)
|
||||
return;
|
||||
|
||||
client.getVirtualGuestClient().cancelService(billingItem.getId());
|
||||
}
|
||||
|
|
|
@ -31,30 +31,38 @@ public class ProductOrderReceipt implements Comparable<ProductOrderReceipt> {
|
|||
|
||||
public static class Builder {
|
||||
private int orderId = -1;
|
||||
private ProductOrder orderDetails;
|
||||
|
||||
public Builder orderId(int orderId) {
|
||||
this.orderId = orderId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder orderDetails(ProductOrder orderDetails) {
|
||||
this.orderDetails = orderDetails;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProductOrderReceipt build() {
|
||||
return new ProductOrderReceipt(orderId);
|
||||
return new ProductOrderReceipt(orderId,orderDetails);
|
||||
}
|
||||
|
||||
public static Builder fromAddress(ProductOrderReceipt in) {
|
||||
return ProductOrderReceipt.builder().orderId(in.getOrderId());
|
||||
return ProductOrderReceipt.builder().orderId(in.getOrderId()).orderDetails(in.getOrderDetails());
|
||||
}
|
||||
}
|
||||
|
||||
private int orderId = -1;
|
||||
private ProductOrder orderDetails;
|
||||
|
||||
// for deserializer
|
||||
ProductOrderReceipt() {
|
||||
|
||||
}
|
||||
|
||||
public ProductOrderReceipt(int orderId) {
|
||||
public ProductOrderReceipt(int orderId,ProductOrder orderDetails) {
|
||||
this.orderId = orderId;
|
||||
this.orderDetails = orderDetails;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,6 +77,16 @@ public class ProductOrderReceipt implements Comparable<ProductOrderReceipt> {
|
|||
return orderId;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a copy of the SoftLayer_Container_Product_Order
|
||||
* which holds all the data related to an order.
|
||||
* This will only return when an order is processed successfully.
|
||||
* It will contain all the items in an order as well as the order totals.
|
||||
*/
|
||||
public ProductOrder getOrderDetails() {
|
||||
return orderDetails;
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return Builder.fromAddress(this);
|
||||
}
|
||||
|
@ -97,7 +115,7 @@ public class ProductOrderReceipt implements Comparable<ProductOrderReceipt> {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[orderId=" + orderId + "]";
|
||||
return "[orderId=" + orderId + ", orderDetails="+orderDetails+"]";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,12 @@ public interface SoftLayerConstants {
|
|||
* Name of the product package corresponding to cloud servers
|
||||
*/
|
||||
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME = "jclouds.softlayer.virtualguest.package-name";
|
||||
|
||||
|
||||
/**
|
||||
* number of milliseconds to wait for an order to arrive on the api.
|
||||
*/
|
||||
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_ORDER_DELAY = "jclouds.softlayer.virtualguest.order-delay";
|
||||
|
||||
public static final Set<ProductItemPrice> DEFAULT_VIRTUAL_GUEST_PRICES = ImmutableSet.<ProductItemPrice>builder()
|
||||
.add(ProductItemPrice.builder().id(1639).build()) // 100 GB (SAN)
|
||||
|
|
|
@ -24,6 +24,7 @@ import static org.testng.Assert.assertEquals;
|
|||
import static org.testng.Assert.assertFalse;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
|
@ -66,7 +67,7 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
|
|||
@Test
|
||||
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
|
||||
String group = "foo";
|
||||
String name = "foo-ef4";
|
||||
String name = "node"+new Random().nextInt();
|
||||
Template template = computeContext.getComputeService().templateBuilder()
|
||||
.locationId("3") // the default (singapore) doesn't work.
|
||||
.build();
|
||||
|
|
Loading…
Reference in New Issue