mirror of https://github.com/apache/jclouds.git
Merge branch 'master' of https://github.com/jsonking/jclouds
* 'master' of https://github.com/jsonking/jclouds: Issue 158: Removed function to find virtual guest - no longer needed issue 384: IsoToMachine + Test started issue 384: IsoToMachine + Test started Issue 158: Property/Predicate/finder to test that the product order got created. Initial timeout of 5s added option to specify domainName as an option when using softlayer fixed location for openhosting to FL, not VA
This commit is contained in:
commit
ae98f06d99
|
@ -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