mirror of https://github.com/apache/jclouds.git
adjusted defaults to allow smallest softlayer size; parameterized configuration; fixed state where guest without billing item was permitted
This commit is contained in:
parent
007ebc693e
commit
d5e130ab3c
|
@ -21,11 +21,20 @@ package org.jclouds.softlayer;
|
||||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||||
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
|
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.PropertiesBuilder;
|
import org.jclouds.PropertiesBuilder;
|
||||||
import org.jclouds.softlayer.reference.SoftLayerConstants;
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds properties used in SoftLayer Clients
|
* Builds properties used in SoftLayer Clients
|
||||||
|
@ -38,9 +47,28 @@ public class SoftLayerPropertiesBuilder extends PropertiesBuilder {
|
||||||
Properties properties = super.defaultProperties();
|
Properties properties = super.defaultProperties();
|
||||||
properties.setProperty(PROPERTY_ENDPOINT, "https://api.softlayer.com/rest");
|
properties.setProperty(PROPERTY_ENDPOINT, "https://api.softlayer.com/rest");
|
||||||
properties.setProperty(PROPERTY_API_VERSION, "3");
|
properties.setProperty(PROPERTY_API_VERSION, "3");
|
||||||
properties.setProperty(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME, "Cloud Server");
|
properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY, "" + 60 * 60 * 1000);
|
||||||
properties.setProperty(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY, ""+60*60*1000);
|
properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME, "Cloud Server");
|
||||||
|
// ex: for private (ex. don't share hardware) use "Private [0-9]+ x ([.0-9]+) GHz Core[s]?"
|
||||||
|
// ex: for private and public use ".*[0-9]+ x ([.0-9]+) GHz Core[s]?"
|
||||||
|
properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX, "[0-9]+ x ([0-9.]+) GHz Core[s]?");
|
||||||
|
// SAN or LOCAL
|
||||||
|
properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE, "LOCAL");
|
||||||
|
// 10, 100, 1000
|
||||||
|
properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED, "10");
|
||||||
properties.setProperty(PROPERTY_ISO3166_CODES, "SG,US-CA,US-TX,US-VA,US-WA,US-TX");
|
properties.setProperty(PROPERTY_ISO3166_CODES, "SG,US-CA,US-TX,US-VA,US-WA,US-TX");
|
||||||
|
Builder<String> prices = ImmutableSet.<String> builder();
|
||||||
|
prices.add("21"); // 1 IP Address
|
||||||
|
prices.add("55"); // Host Ping: categoryCode: monitoring, notification
|
||||||
|
prices.add("57"); // Email and Ticket: categoryCode: notification
|
||||||
|
prices.add("58"); // Automated Notification: categoryCode: response
|
||||||
|
prices.add("1800"); // 0 GB Bandwidth: categoryCode: bandwidth
|
||||||
|
prices.add("905"); // Reboot / Remote Console: categoryCode: remote_management
|
||||||
|
prices.add("418"); // Nessus Vulnerability Assessment & Reporting: categoryCode:
|
||||||
|
// vulnerability_scanner
|
||||||
|
prices.add("420"); // Unlimited SSL VPN Users & 1 PPTP VPN User per account: categoryCode:
|
||||||
|
// vpn_management
|
||||||
|
properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES, Joiner.on(',').join(prices.build()));
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,17 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.compute.config;
|
package org.jclouds.softlayer.compute.config;
|
||||||
|
|
||||||
import java.util.Set;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.collect.Iterables.find;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.compute.ComputeServiceAdapter;
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
@ -28,6 +37,7 @@ import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
||||||
|
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||||
import org.jclouds.softlayer.SoftLayerAsyncClient;
|
import org.jclouds.softlayer.SoftLayerAsyncClient;
|
||||||
import org.jclouds.softlayer.SoftLayerClient;
|
import org.jclouds.softlayer.SoftLayerClient;
|
||||||
import org.jclouds.softlayer.compute.functions.DatacenterToLocation;
|
import org.jclouds.softlayer.compute.functions.DatacenterToLocation;
|
||||||
|
@ -38,19 +48,27 @@ import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
||||||
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
||||||
import org.jclouds.softlayer.domain.Datacenter;
|
import org.jclouds.softlayer.domain.Datacenter;
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
import org.jclouds.softlayer.domain.ProductPackage;
|
||||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
|
import org.jclouds.softlayer.features.AccountClient;
|
||||||
|
import org.jclouds.softlayer.features.ProductPackageClient;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class SoftLayerComputeServiceContextModule extends
|
public class SoftLayerComputeServiceContextModule
|
||||||
ComputeServiceAdapterContextModule<SoftLayerClient, SoftLayerAsyncClient, VirtualGuest, Set<ProductItem>, ProductItem, Datacenter> {
|
extends
|
||||||
|
ComputeServiceAdapterContextModule<SoftLayerClient, SoftLayerAsyncClient, VirtualGuest, Iterable<ProductItem>, ProductItem, Datacenter> {
|
||||||
|
|
||||||
public SoftLayerComputeServiceContextModule() {
|
public SoftLayerComputeServiceContextModule() {
|
||||||
super(SoftLayerClient.class, SoftLayerAsyncClient.class);
|
super(SoftLayerClient.class, SoftLayerAsyncClient.class);
|
||||||
|
@ -59,26 +77,59 @@ public class SoftLayerComputeServiceContextModule extends
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
bind(new TypeLiteral<ComputeServiceAdapter<VirtualGuest, Set<ProductItem>, ProductItem, Datacenter>>() {})
|
bind(new TypeLiteral<ComputeServiceAdapter<VirtualGuest, Iterable<ProductItem>, ProductItem, Datacenter>>() {
|
||||||
.to(SoftLayerComputeServiceAdapter.class);
|
}).to(SoftLayerComputeServiceAdapter.class);
|
||||||
bind(new TypeLiteral<Function<VirtualGuest, NodeMetadata>>() {})
|
bind(new TypeLiteral<Function<VirtualGuest, NodeMetadata>>() {
|
||||||
.to(VirtualGuestToNodeMetadata.class);
|
}).to(VirtualGuestToNodeMetadata.class);
|
||||||
bind(new TypeLiteral<Function<ProductItem, org.jclouds.compute.domain.Image>>() {})
|
bind(new TypeLiteral<Function<ProductItem, org.jclouds.compute.domain.Image>>() {
|
||||||
.to(ProductItemToImage.class);
|
}).to(ProductItemToImage.class);
|
||||||
bind(new TypeLiteral<Function<Set<ProductItem>, org.jclouds.compute.domain.Hardware>>() {})
|
bind(new TypeLiteral<Function<Iterable<ProductItem>, org.jclouds.compute.domain.Hardware>>() {
|
||||||
.to(ProductItemsToHardware.class);
|
}).to(ProductItemsToHardware.class);
|
||||||
bind(new TypeLiteral<Function<Datacenter, Location>>() {})
|
bind(new TypeLiteral<Function<Datacenter, Location>>() {
|
||||||
.to(DatacenterToLocation.class);
|
}).to(DatacenterToLocation.class);
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {})
|
bind(new TypeLiteral<Supplier<Location>>() {
|
||||||
.to(OnlyLocationOrFirstZone.class);
|
}).to(OnlyLocationOrFirstZone.class);
|
||||||
bind(TemplateOptions.class).to(SoftLayerTemplateOptions.class);
|
bind(TemplateOptions.class).to(SoftLayerTemplateOptions.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||||
return template.osFamily(OsFamily.UBUNTU)
|
return template.osFamily(OsFamily.UBUNTU).osVersionMatches("1[10].[10][04]").os64Bit(true).osDescriptionMatches(
|
||||||
.osVersionMatches("1[10].[10][04]")
|
".*Minimal Install.*");
|
||||||
.os64Bit(true)
|
|
||||||
.osDescriptionMatches(".*Minimal Install.*")
|
|
||||||
.minCores(2);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* Many requests need the same productPackage, which is in this case the package for virtual
|
||||||
|
* guests. We may at some point need to make an annotation qualifying it as such. ex. @VirtualGuest
|
||||||
|
*/
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Memoized
|
||||||
|
public Supplier<ProductPackage> getProductPackage(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
|
final SoftLayerClient client,
|
||||||
|
@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME) final String virtualGuestPackageName) {
|
||||||
|
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<ProductPackage>(authException, seconds,
|
||||||
|
new Supplier<ProductPackage>() {
|
||||||
|
@Override
|
||||||
|
public ProductPackage get() {
|
||||||
|
AccountClient accountClient = client.getAccountClient();
|
||||||
|
ProductPackageClient productPackageClient = client.getProductPackageClient();
|
||||||
|
ProductPackage p = find(accountClient.getActivePackages(), named(virtualGuestPackageName));
|
||||||
|
return productPackageClient.getProductPackage(p.getId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check the prices really do exist
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public Iterable<ProductItemPrice> prices(@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES) String prices) {
|
||||||
|
return Iterables.transform(Splitter.on(',').split(checkNotNull(prices, "prices")),
|
||||||
|
new Function<String, ProductItemPrice>() {
|
||||||
|
@Override
|
||||||
|
public ProductItemPrice apply(String arg0) {
|
||||||
|
return ProductItemPrice.builder().id(Integer.parseInt(arg0)).build();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -29,63 +29,63 @@ import java.util.Set;
|
||||||
|
|
||||||
public class ProductItems {
|
public class ProductItems {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a function to get the capacity from a product item.
|
* Creates a function to get the capacity from a product item.
|
||||||
*/
|
*/
|
||||||
public static Function<ProductItem,Float> capacity() {
|
public static Function<ProductItem, Float> capacity() {
|
||||||
return new Function<ProductItem,Float>() {
|
return new Function<ProductItem, Float>() {
|
||||||
@Override
|
@Override
|
||||||
public Float apply(ProductItem productItem) {
|
public Float apply(ProductItem productItem) {
|
||||||
return productItem.getCapacity();
|
return productItem.getCapacity();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a function to get the description from a product item.
|
|
||||||
*/
|
|
||||||
public static Function<ProductItem,String> description() {
|
|
||||||
return new Function<ProductItem,String>() {
|
|
||||||
@Override
|
|
||||||
public String apply(ProductItem productItem) {
|
|
||||||
return productItem.getDescription();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a function to get the ProductItemPrice for the ProductItem.
|
|
||||||
* Currently returns the first price.
|
|
||||||
* This will need to be changed if more than one price is returned.
|
|
||||||
*/
|
|
||||||
public static Function<ProductItem,ProductItemPrice> price() {
|
|
||||||
return new Function<ProductItem,ProductItemPrice>() {
|
|
||||||
@Override
|
|
||||||
public ProductItemPrice apply(ProductItem productItem) {
|
|
||||||
if(productItem.getPrices().size()<1) throw new NoSuchElementException("ProductItem has no prices:"+productItem);
|
|
||||||
return Iterables.get(productItem.getPrices(), 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a function to get the ProductItem for the ProductItemPrice.
|
* Creates a function to get the description from a product item.
|
||||||
* Copies the category information from the price to the item if necessary
|
*/
|
||||||
* The ProductItemPrices must have ProductItems.
|
public static Function<ProductItem, String> description() {
|
||||||
*/
|
return new Function<ProductItem, String>() {
|
||||||
public static Function<ProductItemPrice,ProductItem> item() {
|
@Override
|
||||||
return new Function<ProductItemPrice,ProductItem>() {
|
public String apply(ProductItem productItem) {
|
||||||
@Override
|
return productItem.getDescription();
|
||||||
public ProductItem apply(ProductItemPrice productItemPrice) {
|
}
|
||||||
Set<ProductItemCategory> categories = productItemPrice.getCategories();
|
};
|
||||||
ProductItem item = productItemPrice.getItem();
|
}
|
||||||
ProductItem.Builder builder = ProductItem.Builder.fromProductItem(productItemPrice.getItem());
|
|
||||||
if( item.getCategories().size()==0 && categories.size() != 0) {
|
|
||||||
builder.categories(categories);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
/**
|
||||||
|
* Creates a function to get the ProductItemPrice for the ProductItem. Currently returns the
|
||||||
|
* first price. This will need to be changed if more than one price is returned.
|
||||||
|
*/
|
||||||
|
public static Function<ProductItem, ProductItemPrice> price() {
|
||||||
|
return new Function<ProductItem, ProductItemPrice>() {
|
||||||
|
@Override
|
||||||
|
public ProductItemPrice apply(ProductItem productItem) {
|
||||||
|
if (productItem.getPrices().size() < 1)
|
||||||
|
throw new NoSuchElementException("ProductItem has no prices:" + productItem);
|
||||||
|
return Iterables.get(productItem.getPrices(), 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a function to get the ProductItem for the ProductItemPrice. Copies the category
|
||||||
|
* information from the price to the item if necessary The ProductItemPrices must have
|
||||||
|
* ProductItems.
|
||||||
|
*/
|
||||||
|
public static Function<ProductItemPrice, ProductItem> item() {
|
||||||
|
return new Function<ProductItemPrice, ProductItem>() {
|
||||||
|
@Override
|
||||||
|
public ProductItem apply(ProductItemPrice productItemPrice) {
|
||||||
|
Set<ProductItemCategory> categories = productItemPrice.getCategories();
|
||||||
|
ProductItem item = productItemPrice.getItem();
|
||||||
|
ProductItem.Builder builder = ProductItem.Builder.fromProductItem(productItemPrice.getItem());
|
||||||
|
if (item.getCategories().size() == 0 && categories.size() != 0) {
|
||||||
|
builder.categories(categories);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
return builder.build();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,73 +18,101 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.compute.functions;
|
package org.jclouds.softlayer.compute.functions;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import com.google.common.collect.ImmutableList;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
|
import static com.google.common.collect.Iterables.get;
|
||||||
|
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCodeMatches;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.matches;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.HardwareBuilder;
|
import org.jclouds.compute.domain.HardwareBuilder;
|
||||||
import org.jclouds.compute.domain.Processor;
|
import org.jclouds.compute.domain.Processor;
|
||||||
import org.jclouds.compute.domain.Volume;
|
import org.jclouds.compute.domain.Volume;
|
||||||
import org.jclouds.compute.domain.internal.VolumeImpl;
|
import org.jclouds.compute.domain.internal.VolumeImpl;
|
||||||
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import com.google.common.base.Function;
|
||||||
import java.util.List;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.util.Set;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.filter;
|
|
||||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
|
||||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a set of ProductItems to Hardware.
|
* Converts a set of ProductItems to Hardware. All cores have a speed of 2.0Ghz The Hardware Id will
|
||||||
* All cores have a speed of 2.0Ghz
|
* be a comma separated list containing the price ids: cpus,ram,volume
|
||||||
* The Hardware Id will be a comma separated list containing the price ids:
|
*
|
||||||
* cpus,ram,volume
|
|
||||||
*
|
|
||||||
* @author Jason King
|
* @author Jason King
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ProductItemsToHardware implements Function<Set<ProductItem>, Hardware> {
|
public class ProductItemsToHardware implements Function<Iterable<ProductItem>, Hardware> {
|
||||||
|
|
||||||
static final double CORE_SPEED = 2.0;
|
private final Pattern cpuRegex;
|
||||||
|
private final Pattern categoryCodeMatches;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ProductItemsToHardware(@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX) String cpuRegex) {
|
||||||
|
this(Pattern.compile(checkNotNull(cpuRegex, "cpuRegex")), Pattern.compile("guest_disk[0-9]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProductItemsToHardware(Pattern cpuRegex, Pattern categoryCodeMatches) {
|
||||||
|
this.cpuRegex = checkNotNull(cpuRegex, "cpuRegex");
|
||||||
|
this.categoryCodeMatches = checkNotNull(categoryCodeMatches, "categoryCodeMatches");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Hardware apply(Set<ProductItem> items) {
|
public Hardware apply(Iterable<ProductItem> items) {
|
||||||
|
|
||||||
ProductItem coresItem = getOnlyElement(filter(items, units("PRIVATE_CORE")));
|
ProductItem coresItem = getOnlyElement(filter(items, matches(cpuRegex)));
|
||||||
ProductItem ramItem = getOnlyElement(filter(items, categoryCode("ram")));
|
ProductItem ramItem = getOnlyElement(filter(items, categoryCode("ram")));
|
||||||
ProductItem volumeItem = getOnlyElement(filter(items, matches(SoftLayerComputeServiceAdapter.SAN_DESCRIPTION_REGEX)));
|
ProductItem volumeItem = get(filter(items, categoryCode("guest_disk0")), 0);
|
||||||
|
|
||||||
final String hardwareId = hardwareId().apply(ImmutableList.of(coresItem, ramItem, volumeItem));
|
String hardwareId = hardwareId().apply(ImmutableList.of(coresItem, ramItem, volumeItem));
|
||||||
final double cores = ProductItems.capacity().apply(coresItem).doubleValue();
|
double cores = ProductItems.capacity().apply(coresItem).doubleValue();
|
||||||
final int ram = ProductItems.capacity().apply(ramItem).intValue();
|
Matcher cpuMatcher = cpuRegex.matcher(coresItem.getDescription());
|
||||||
final float volumeSize = ProductItems.capacity().apply(volumeItem);
|
double coreSpeed = (cpuMatcher.matches()) ? Double.parseDouble(cpuMatcher.group(cpuMatcher.groupCount())) : 2.0;
|
||||||
|
int ram = ProductItems.capacity().apply(ramItem).intValue();
|
||||||
|
|
||||||
return new HardwareBuilder()
|
return new HardwareBuilder().ids(hardwareId).processors(ImmutableList.of(new Processor(cores, coreSpeed))).ram(
|
||||||
.ids(hardwareId)
|
ram).volumes(
|
||||||
.processors(ImmutableList.of(new Processor(cores, CORE_SPEED)))
|
Iterables.transform(filter(items, categoryCodeMatches(categoryCodeMatches)),
|
||||||
.ram(ram)
|
new Function<ProductItem, Volume>() {
|
||||||
.volumes(ImmutableList.<Volume> of(new VolumeImpl(volumeSize, true, false)))
|
|
||||||
.build();
|
@Override
|
||||||
|
public Volume apply(ProductItem arg0) {
|
||||||
|
float volumeSize = ProductItems.capacity().apply(arg0);
|
||||||
|
return new VolumeImpl(
|
||||||
|
arg0.getId() + "",
|
||||||
|
arg0.getDescription().indexOf("SAN") != -1 ? Volume.Type.SAN : Volume.Type.LOCAL,
|
||||||
|
volumeSize, null, categoryCode("guest_disk0").apply(arg0), false);
|
||||||
|
}
|
||||||
|
})).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a hardwareId based on the priceId's of the items in the list
|
* Generates a hardwareId based on the priceId's of the items in the list
|
||||||
|
*
|
||||||
* @return comma separated list of priceid's
|
* @return comma separated list of priceid's
|
||||||
*/
|
*/
|
||||||
public static Function<List<ProductItem>,String> hardwareId() {
|
public static Function<List<ProductItem>, String> hardwareId() {
|
||||||
return new Function<List<ProductItem>,String>() {
|
return new Function<List<ProductItem>, String>() {
|
||||||
@Override
|
@Override
|
||||||
public String apply(List<ProductItem> productItems) {
|
public String apply(List<ProductItem> productItems) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for(ProductItem item:productItems) {
|
for (ProductItem item : productItems) {
|
||||||
ProductItemPrice price = ProductItems.price().apply(item);
|
ProductItemPrice price = ProductItems.price().apply(item);
|
||||||
builder.append(price.getId())
|
builder.append(price.getId()).append(",");
|
||||||
.append(",");
|
|
||||||
}
|
}
|
||||||
return builder.toString().substring(0,builder.lastIndexOf(","));
|
return builder.toString().substring(0, builder.lastIndexOf(","));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,6 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||||
import org.jclouds.compute.domain.NodeState;
|
import org.jclouds.compute.domain.NodeState;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.http.HttpResponseException;
|
|
||||||
import org.jclouds.softlayer.SoftLayerClient;
|
import org.jclouds.softlayer.SoftLayerClient;
|
||||||
import org.jclouds.softlayer.domain.Datacenter;
|
import org.jclouds.softlayer.domain.Datacenter;
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
|
@ -49,7 +48,6 @@ import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -129,25 +127,24 @@ public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMe
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class GetHardwareForVirtualGuest {
|
public static class GetHardwareForVirtualGuest {
|
||||||
|
|
||||||
private SoftLayerClient client;
|
private final SoftLayerClient client;
|
||||||
|
private final Function<Iterable<ProductItem>, Hardware> productItemsToHardware;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GetHardwareForVirtualGuest(SoftLayerClient client) {
|
public GetHardwareForVirtualGuest(SoftLayerClient client,
|
||||||
this.client = client;
|
Function<Iterable<ProductItem>, Hardware> productItemsToHardware) {
|
||||||
|
this.client = checkNotNull(client, "client");
|
||||||
|
this.productItemsToHardware = checkNotNull(productItemsToHardware, "productItemsToHardware");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hardware getHardware(VirtualGuest guest) {
|
public Hardware getHardware(VirtualGuest guest) {
|
||||||
// 'bad' orders have no start cpu's and cause the order lookup to fail.
|
// 'bad' orders have no start cpu's and cause the order lookup to fail.
|
||||||
if (guest.getStartCpus() < 1)
|
if (guest.getStartCpus() < 1)
|
||||||
return null;
|
return null;
|
||||||
try {
|
ProductOrder order = client.getVirtualGuestClient().getOrderTemplate(guest.getId());
|
||||||
ProductOrder order = client.getVirtualGuestClient().getOrderTemplate(guest.getId());
|
Iterable<ProductItem> items = Iterables.transform(order.getPrices(), ProductItems.item());
|
||||||
Iterable<ProductItem> items = Iterables.transform(order.getPrices(), ProductItems.item());
|
return productItemsToHardware.apply(items);
|
||||||
return new ProductItemsToHardware().apply(Sets.newLinkedHashSet(items));
|
|
||||||
} catch (HttpResponseException e) {
|
|
||||||
// Shouldn't happen any more - was blowing up in Singapore
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,15 +162,10 @@ public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMe
|
||||||
// 'bad' orders have no start cpu's and cause the order lookup to fail.
|
// 'bad' orders have no start cpu's and cause the order lookup to fail.
|
||||||
if (guest.getStartCpus() < 1)
|
if (guest.getStartCpus() < 1)
|
||||||
return null;
|
return null;
|
||||||
try {
|
ProductOrder order = client.getVirtualGuestClient().getOrderTemplate(guest.getId());
|
||||||
ProductOrder order = client.getVirtualGuestClient().getOrderTemplate(guest.getId());
|
Iterable<ProductItem> items = Iterables.transform(order.getPrices(), ProductItems.item());
|
||||||
Iterable<ProductItem> items = Iterables.transform(order.getPrices(), ProductItems.item());
|
ProductItem os = Iterables.find(items, ProductItemPredicates.categoryCode("os"));
|
||||||
ProductItem os = Iterables.find(items, ProductItemPredicates.categoryCode("os"));
|
return new ProductItemToImage().apply(os);
|
||||||
return new ProductItemToImage().apply(os);
|
|
||||||
} catch (HttpResponseException e) {
|
|
||||||
// Shouldn't happen any more - was blowing up in Singapore
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,37 +18,54 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.compute.strategy;
|
package org.jclouds.softlayer.compute.strategy;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
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;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.softlayer.SoftLayerClient;
|
|
||||||
import org.jclouds.softlayer.compute.functions.ProductItems;
|
|
||||||
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
|
||||||
import org.jclouds.softlayer.domain.*;
|
|
||||||
import org.jclouds.softlayer.features.AccountClient;
|
|
||||||
import org.jclouds.softlayer.features.ProductPackageClient;
|
|
||||||
import org.jclouds.softlayer.reference.SoftLayerConstants;
|
|
||||||
|
|
||||||
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.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
import static com.google.common.base.Predicates.and;
|
||||||
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
|
import static com.google.common.collect.Iterables.find;
|
||||||
|
import static com.google.common.collect.Iterables.get;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.capacity;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.matches;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.collect.Memoized;
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
import org.jclouds.softlayer.SoftLayerClient;
|
||||||
|
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
||||||
|
import org.jclouds.softlayer.domain.Datacenter;
|
||||||
|
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.ProductOrderReceipt;
|
||||||
|
import org.jclouds.softlayer.domain.ProductPackage;
|
||||||
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds
|
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds
|
||||||
|
@ -57,28 +74,40 @@ import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class SoftLayerComputeServiceAdapter implements
|
public class SoftLayerComputeServiceAdapter implements
|
||||||
ComputeServiceAdapter<VirtualGuest, Set<ProductItem>, ProductItem, Datacenter> {
|
ComputeServiceAdapter<VirtualGuest, Iterable<ProductItem>, ProductItem, Datacenter> {
|
||||||
|
|
||||||
public static final String SAN_DESCRIPTION_REGEX = ".*GB \\(SAN\\).*";
|
@Resource
|
||||||
private static final Float BOOT_VOLUME_CAPACITY = 100F;
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
private final SoftLayerClient client;
|
private final SoftLayerClient client;
|
||||||
private final String virtualGuestPackageName;
|
private final Supplier<ProductPackage> productPackageSupplier;
|
||||||
private final RetryablePredicate<VirtualGuest> loginDetailsTester;
|
private final RetryablePredicate<VirtualGuest> loginDetailsTester;
|
||||||
private final long guestLoginDelay;
|
private final long guestLoginDelay;
|
||||||
|
private final Pattern cpuPattern;
|
||||||
|
private final Pattern disk0Type;
|
||||||
|
private final float portSpeed;
|
||||||
|
private final Iterable<ProductItemPrice> prices;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SoftLayerComputeServiceAdapter(SoftLayerClient client,
|
public SoftLayerComputeServiceAdapter(SoftLayerClient client,
|
||||||
@Named(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME) String virtualGuestPackageName,
|
|
||||||
VirtualGuestHasLoginDetailsPresent virtualGuestHasLoginDetailsPresent,
|
VirtualGuestHasLoginDetailsPresent virtualGuestHasLoginDetailsPresent,
|
||||||
@Named(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY) long guestLoginDelay) {
|
@Memoized Supplier<ProductPackage> productPackageSupplier, Iterable<ProductItemPrice> prices,
|
||||||
|
@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX) String cpuRegex,
|
||||||
|
@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE) String disk0Type,
|
||||||
|
@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED) float portSpeed,
|
||||||
|
@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY) long guestLoginDelay) {
|
||||||
this.client = checkNotNull(client, "client");
|
this.client = checkNotNull(client, "client");
|
||||||
this.virtualGuestPackageName = checkNotNull(virtualGuestPackageName, "virtualGuestPackageName");
|
this.guestLoginDelay = guestLoginDelay;
|
||||||
|
this.productPackageSupplier = checkNotNull(productPackageSupplier, "productPackageSupplier");
|
||||||
checkArgument(guestLoginDelay > 500, "guestOrderDelay must be in milliseconds and greater than 500");
|
checkArgument(guestLoginDelay > 500, "guestOrderDelay must be in milliseconds and greater than 500");
|
||||||
this.guestLoginDelay =guestLoginDelay;
|
|
||||||
|
|
||||||
this.loginDetailsTester = new RetryablePredicate<VirtualGuest>(virtualGuestHasLoginDetailsPresent,
|
this.loginDetailsTester = new RetryablePredicate<VirtualGuest>(virtualGuestHasLoginDetailsPresent,
|
||||||
guestLoginDelay);
|
guestLoginDelay);
|
||||||
|
this.cpuPattern = Pattern.compile(checkNotNull(cpuRegex, "cpuRegex"));
|
||||||
|
this.prices = checkNotNull(prices, "prices");
|
||||||
|
this.portSpeed = portSpeed;
|
||||||
|
checkArgument(portSpeed > 0, "portSpeed must be greater than zero, often 10, 100, 1000, 10000");
|
||||||
|
this.disk0Type = Pattern.compile(".*" + checkNotNull(disk0Type, "disk0Type") + ".*");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -87,34 +116,38 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
checkNotNull(template, "template was null");
|
checkNotNull(template, "template was null");
|
||||||
checkNotNull(template.getOptions(), "template options was null");
|
checkNotNull(template.getOptions(), "template options was null");
|
||||||
checkArgument(template.getOptions().getClass().isAssignableFrom(SoftLayerTemplateOptions.class),
|
checkArgument(template.getOptions().getClass().isAssignableFrom(SoftLayerTemplateOptions.class),
|
||||||
"options class %s should have been assignable from SoftLayerTemplateOptions", template.getOptions()
|
"options class %s should have been assignable from SoftLayerTemplateOptions", template.getOptions()
|
||||||
.getClass());
|
.getClass());
|
||||||
|
|
||||||
String domainName = template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName();
|
String domainName = template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName();
|
||||||
|
|
||||||
VirtualGuest newGuest = VirtualGuest.builder().domain(domainName).hostname(name).build();
|
VirtualGuest newGuest = VirtualGuest.builder().domain(domainName).hostname(name).build();
|
||||||
|
|
||||||
ProductOrder order = ProductOrder.builder().packageId(getProductPackage().getId()).location(
|
ProductOrder order = ProductOrder.builder().packageId(productPackageSupplier.get().getId()).location(
|
||||||
template.getLocation().getId()).quantity(1).useHourlyPricing(true).prices(getPrices(template))
|
template.getLocation().getId()).quantity(1).useHourlyPricing(true).prices(getPrices(template))
|
||||||
.virtualGuest(newGuest).build();
|
.virtualGuest(newGuest).build();
|
||||||
|
|
||||||
|
logger.debug(">> ordering new virtualGuest domain(%s) hostname(%s)", domainName, name);
|
||||||
ProductOrderReceipt productOrderReceipt = client.getVirtualGuestClient().orderVirtualGuest(order);
|
ProductOrderReceipt productOrderReceipt = client.getVirtualGuestClient().orderVirtualGuest(order);
|
||||||
VirtualGuest result = Iterables.get(productOrderReceipt.getOrderDetails().getVirtualGuests(), 0);
|
VirtualGuest result = get(productOrderReceipt.getOrderDetails().getVirtualGuests(), 0);
|
||||||
|
logger.trace("<< virtualGuest(%s)", result.getId());
|
||||||
|
|
||||||
|
logger.debug(">> awaiting login details for virtualGuest(%s)", result.getId());
|
||||||
boolean orderInSystem = loginDetailsTester.apply(result);
|
boolean orderInSystem = loginDetailsTester.apply(result);
|
||||||
|
logger.trace("<< virtualGuest(%s) complete(%s)", result.getId(), orderInSystem);
|
||||||
|
|
||||||
checkState(orderInSystem, "order for guest %s doesn't have login details within %sms", result, Long.toString(guestLoginDelay));
|
checkState(orderInSystem, "order for guest %s doesn't have login details within %sms", result, Long
|
||||||
|
.toString(guestLoginDelay));
|
||||||
result = client.getVirtualGuestClient().getVirtualGuest(result.getId());
|
result = client.getVirtualGuestClient().getVirtualGuest(result.getId());
|
||||||
|
|
||||||
Password pw = Iterables.get(result.getOperatingSystem().getPasswords(),0);
|
Password pw = get(result.getOperatingSystem().getPasswords(), 0);
|
||||||
Credentials credentials = new Credentials(pw.getUsername(), pw.getPassword());
|
Credentials credentials = new Credentials(pw.getUsername(), pw.getPassword());
|
||||||
credentialStore.put("node#" + result.getId(), credentials);
|
credentialStore.put("node#" + result.getId(), credentials);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Iterable<ProductItemPrice> getPrices(Template template) {
|
private Iterable<ProductItemPrice> getPrices(Template template) {
|
||||||
Set<ProductItemPrice> result = Sets.newLinkedHashSet();
|
Builder<ProductItemPrice> result = ImmutableSet.<ProductItemPrice> builder();
|
||||||
|
|
||||||
int imageId = Integer.parseInt(template.getImage().getId());
|
int imageId = Integer.parseInt(template.getImage().getId());
|
||||||
result.add(ProductItemPrice.builder().id(imageId).build());
|
result.add(ProductItemPrice.builder().id(imageId).build());
|
||||||
|
@ -124,46 +157,31 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
int id = Integer.parseInt(hardwareId);
|
int id = Integer.parseInt(hardwareId);
|
||||||
result.add(ProductItemPrice.builder().id(id).build());
|
result.add(ProductItemPrice.builder().id(id).build());
|
||||||
}
|
}
|
||||||
|
ProductItem uplinkItem = find(productPackageSupplier.get().getItems(), and(capacity(portSpeed),
|
||||||
result.addAll(SoftLayerConstants.DEFAULT_VIRTUAL_GUEST_PRICES);
|
categoryCode("port_speed")));
|
||||||
|
result.add(get(uplinkItem.getPrices(), 0));
|
||||||
return result;
|
result.addAll(prices);
|
||||||
|
return result.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Set<ProductItem>> listHardwareProfiles() {
|
public Iterable<Iterable<ProductItem>> listHardwareProfiles() {
|
||||||
ProductPackage productPackage = getProductPackage();
|
ProductPackage productPackage = productPackageSupplier.get();
|
||||||
Set<ProductItem> items = productPackage.getItems();
|
Set<ProductItem> items = productPackage.getItems();
|
||||||
|
Builder<Iterable<ProductItem>> result = ImmutableSet.<Iterable<ProductItem>> builder();
|
||||||
Iterable<ProductItem> cpuItems = Iterables.filter(items, units("PRIVATE_CORE"));
|
for (ProductItem cpuItem : filter(items, matches(cpuPattern))) {
|
||||||
Iterable<ProductItem> ramItems = Iterables.filter(items, categoryCode("ram"));
|
for (ProductItem ramItem : filter(items, categoryCode("ram"))) {
|
||||||
Iterable<ProductItem> sanItems = Iterables.filter(items, Predicates.and(matches(SAN_DESCRIPTION_REGEX),
|
for (ProductItem sanItem : filter(items, and(matches(disk0Type), categoryCode("guest_disk0")))) {
|
||||||
categoryCode("one_time_charge")));
|
result.add(ImmutableSet.of(cpuItem, ramItem, sanItem));
|
||||||
|
}
|
||||||
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;
|
|
||||||
|
|
||||||
Set<Set<ProductItem>> result = Sets.newLinkedHashSet();
|
|
||||||
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;
|
|
||||||
|
|
||||||
result.add(ImmutableSet.of(coresEntry.getValue(), ramItem, bootVolume));
|
|
||||||
}
|
}
|
||||||
|
return result.build();
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<ProductItem> listImages() {
|
public Iterable<ProductItem> listImages() {
|
||||||
return Iterables.filter(getProductPackage().getItems(), categoryCode("os"));
|
return filter(productPackageSupplier.get().getItems(), categoryCode("os"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -173,15 +191,7 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Datacenter> listLocations() {
|
public Iterable<Datacenter> listLocations() {
|
||||||
return getProductPackage().getDatacenters();
|
return productPackageSupplier.get().getDatacenters();
|
||||||
}
|
|
||||||
|
|
||||||
private ProductPackage getProductPackage() {
|
|
||||||
AccountClient accountClient = client.getAccountClient();
|
|
||||||
ProductPackageClient productPackageClient = client.getProductPackageClient();
|
|
||||||
|
|
||||||
ProductPackage p = Iterables.find(accountClient.getActivePackages(), named(virtualGuestPackageName));
|
|
||||||
return productPackageClient.getProductPackage(p.getId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -197,8 +207,10 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (guest.getBillingItemId() == -1)
|
if (guest.getBillingItemId() == -1)
|
||||||
return;
|
throw new IllegalStateException(String.format("no billing item for guest(%s) so we cannot cancel the order",
|
||||||
|
id));
|
||||||
|
|
||||||
|
logger.debug(">> canceling service for guest(%s) billingItem(%s)", id, guest.getBillingItemId());
|
||||||
client.getVirtualGuestClient().cancelService(guest.getBillingItemId());
|
client.getVirtualGuestClient().cancelService(guest.getBillingItemId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +244,8 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
VirtualGuest newGuest = client.getVirtualGuestClient().getVirtualGuest(guest.getId());
|
VirtualGuest newGuest = client.getVirtualGuestClient().getVirtualGuest(guest.getId());
|
||||||
boolean hasBackendIp = newGuest.getPrimaryBackendIpAddress() != null;
|
boolean hasBackendIp = newGuest.getPrimaryBackendIpAddress() != null;
|
||||||
boolean hasPrimaryIp = newGuest.getPrimaryIpAddress() != null;
|
boolean hasPrimaryIp = newGuest.getPrimaryIpAddress() != null;
|
||||||
boolean hasPasswords = newGuest.getOperatingSystem()!=null && newGuest.getOperatingSystem().getPasswords().size() > 0;
|
boolean hasPasswords = newGuest.getOperatingSystem() != null
|
||||||
|
&& newGuest.getOperatingSystem().getPasswords().size() > 0;
|
||||||
|
|
||||||
return hasBackendIp && hasPrimaryIp && hasPasswords;
|
return hasBackendIp && hasPrimaryIp && hasPasswords;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,93 +30,126 @@ public class ProductItemPredicates {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if the ProductItem contains the required category.
|
* Tests if the ProductItem contains the required category.
|
||||||
|
*
|
||||||
* @param category
|
* @param category
|
||||||
* @return true if it does, otherwise false.
|
* @return true if it does, otherwise false.
|
||||||
*/
|
*/
|
||||||
public static Predicate<ProductItem> categoryCode(final String category) {
|
public static Predicate<ProductItem> categoryCode(final String category) {
|
||||||
checkNotNull(category, "category cannot be null");
|
checkNotNull(category, "category cannot be null");
|
||||||
return new Predicate<ProductItem>() {
|
return new Predicate<ProductItem>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(ProductItem productItem) {
|
public boolean apply(ProductItem productItem) {
|
||||||
checkNotNull(productItem, "productItem cannot ne null");
|
checkNotNull(productItem, "productItem cannot ne null");
|
||||||
for(ProductItemCategory productItemCategory: productItem.getCategories()) {
|
for (ProductItemCategory productItemCategory : productItem.getCategories()) {
|
||||||
if(category.equals(productItemCategory.getCategoryCode())) return true;
|
if (category.equals(productItemCategory.getCategoryCode()))
|
||||||
}
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "categoryCode("+category+")";
|
return "categoryCode(" + category + ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the ProductItem contains a category that matches the supplied Pattern
|
||||||
|
*
|
||||||
|
* @param category
|
||||||
|
* @return true if it does, otherwise false.
|
||||||
|
*/
|
||||||
|
public static Predicate<ProductItem> categoryCodeMatches(final Pattern category) {
|
||||||
|
checkNotNull(category, "category cannot be null");
|
||||||
|
return new Predicate<ProductItem>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(ProductItem productItem) {
|
||||||
|
checkNotNull(productItem, "productItem cannot ne null");
|
||||||
|
for (ProductItemCategory productItemCategory : productItem.getCategories()) {
|
||||||
|
if (category.matcher(productItemCategory.getCategoryCode()).matches())
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "categoryCodeMatches(" + category + ")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* Tests if the ProductItem has the required capacity.
|
* Tests if the ProductItem has the required capacity.
|
||||||
|
*
|
||||||
* @param capacity
|
* @param capacity
|
||||||
* @return true if it does, otherwise false.
|
* @return true if it does, otherwise false.
|
||||||
*/
|
*/
|
||||||
public static Predicate<ProductItem> capacity(final Float capacity) {
|
public static Predicate<ProductItem> capacity(final Float capacity) {
|
||||||
checkNotNull(capacity, "capacity cannot be null");
|
checkNotNull(capacity, "capacity cannot be null");
|
||||||
return new Predicate<ProductItem>() {
|
return new Predicate<ProductItem>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(ProductItem productItem) {
|
public boolean apply(ProductItem productItem) {
|
||||||
checkNotNull(productItem, "productItem cannot ne null");
|
checkNotNull(productItem, "productItem cannot ne null");
|
||||||
Float productItemCapacity = productItem.getCapacity();
|
Float productItemCapacity = productItem.getCapacity();
|
||||||
if (productItemCapacity == null) return false;
|
if (productItemCapacity == null)
|
||||||
return capacity.equals(productItemCapacity);
|
return false;
|
||||||
}
|
return capacity.equals(productItemCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "capacity("+capacity+")";
|
return "capacity(" + capacity + ")";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if the ProductItem has the required units.
|
* Tests if the ProductItem has the required units.
|
||||||
|
*
|
||||||
* @param units
|
* @param units
|
||||||
* @return true if it does, otherwise false.
|
* @return true if it does, otherwise false.
|
||||||
*/
|
*/
|
||||||
public static Predicate<ProductItem> units(final String units) {
|
public static Predicate<ProductItem> units(final String units) {
|
||||||
checkNotNull(units, "units cannot be null");
|
checkNotNull(units, "units cannot be null");
|
||||||
return new Predicate<ProductItem>() {
|
return new Predicate<ProductItem>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(ProductItem productItem) {
|
public boolean apply(ProductItem productItem) {
|
||||||
checkNotNull(productItem, "productItem cannot ne null");
|
checkNotNull(productItem, "productItem cannot ne null");
|
||||||
return units.equals(productItem.getUnits());
|
return units.equals(productItem.getUnits());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "units("+units+")";
|
return "units(" + units + ")";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if the ProductItem's description matches the supplied regular expression.
|
* Tests if the ProductItem's description matches the supplied regular expression.
|
||||||
* @param regex a regular expression to match against.
|
*
|
||||||
|
* @param regex
|
||||||
|
* a regular expression to match against.
|
||||||
* @return true if it does, otherwise false.
|
* @return true if it does, otherwise false.
|
||||||
* @throws java.util.regex.PatternSyntaxException if the regex is invalid
|
* @throws java.util.regex.PatternSyntaxException
|
||||||
|
* if the regex is invalid
|
||||||
*/
|
*/
|
||||||
public static Predicate<ProductItem> matches(final String regex) {
|
public static Predicate<ProductItem> matches(final Pattern regex) {
|
||||||
checkNotNull(regex, "regex cannot be null");
|
checkNotNull(regex, "regex cannot be null");
|
||||||
final Pattern PATTERN = Pattern.compile(regex);
|
|
||||||
|
|
||||||
return new Predicate<ProductItem>() {
|
return new Predicate<ProductItem>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(ProductItem productItem) {
|
public boolean apply(ProductItem productItem) {
|
||||||
checkNotNull(productItem, "productItem cannot ne null");
|
checkNotNull(productItem, "productItem cannot ne null");
|
||||||
return PATTERN.matcher(productItem.getDescription()).matches();
|
return regex.matcher(productItem.getDescription()).matches();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "regex("+regex+")";
|
return "regex(" + regex + ")";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,38 +18,41 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.reference;
|
package org.jclouds.softlayer.reference;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration properties and constants used in SoftLayer connections.
|
* Configuration properties and constants used in SoftLayer connections.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public interface SoftLayerConstants {
|
public interface SoftLayerConstants {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the product package corresponding to cloud servers
|
* Name of the product package corresponding to cloud servers
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME = "jclouds.softlayer.virtualguest.package-name";
|
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME = "jclouds.softlayer.virtualguest.package-name";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pattern where last group matches core speed
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX = "jclouds.softlayer.virtualguest.cpu-regex";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uplink port speed for new guests (10, 100, 1000)
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED = "jclouds.softlayer.virtualguest.port-speed";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Boot Disk type (SAN, LOCAL)
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE = "jclouds.softlayer.virtualguest.disk0-type";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* number of milliseconds to wait for an order to arrive on the api.
|
* number of milliseconds to wait for an order to arrive on the api.
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY = "jclouds.softlayer.virtualguest.order-delay";
|
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_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)
|
* standard prices for all new guests.
|
||||||
.add(ProductItemPrice.builder().id(21).build()) // 1 IP Address
|
*/
|
||||||
.add(ProductItemPrice.builder().id(55).build()) // Host Ping
|
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES = "jclouds.softlayer.virtualguest.prices";
|
||||||
.add(ProductItemPrice.builder().id(58).build()) // Automated Notification
|
|
||||||
.add(ProductItemPrice.builder().id(1800).build()) // 0 GB Bandwidth
|
|
||||||
.add(ProductItemPrice.builder().id(57).build()) // Email and Ticket
|
|
||||||
.add(ProductItemPrice.builder().id(274).build()) // 1000 Mbps Public & Private Networks
|
|
||||||
.add(ProductItemPrice.builder().id(905).build()) // Reboot / Remote Console
|
|
||||||
.add(ProductItemPrice.builder().id(418).build()) // Nessus Vulnerability Assessment & Reporting
|
|
||||||
.add(ProductItemPrice.builder().id(420).build()) // Unlimited SSL VPN Users & 1 PPTP VPN User per account
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,25 +18,22 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.compute;
|
package org.jclouds.softlayer.compute;
|
||||||
|
|
||||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
|
|
||||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
import org.jclouds.compute.domain.ExecResponse;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.net.IPSocket;
|
import org.jclouds.net.IPSocket;
|
||||||
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
||||||
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
import org.jclouds.softlayer.features.BaseSoftLayerClientLiveTest;
|
import org.jclouds.softlayer.features.BaseSoftLayerClientLiveTest;
|
||||||
import org.jclouds.softlayer.features.ProductPackageClientLiveTest;
|
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.testng.annotations.AfterGroups;
|
import org.testng.annotations.AfterGroups;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
@ -45,6 +42,7 @@ import org.testng.annotations.Test;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.net.InetAddresses;
|
import com.google.common.net.InetAddresses;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
|
||||||
@Test(groups = "live", singleThreaded = true, testName = "SoftLayerComputeServiceAdapterLiveTest")
|
@Test(groups = "live", singleThreaded = true, testName = "SoftLayerComputeServiceAdapterLiveTest")
|
||||||
public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientLiveTest {
|
public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
|
@ -55,9 +53,8 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
super.setupClient();
|
super.setupClient();
|
||||||
adapter = new SoftLayerComputeServiceAdapter(context.getApi(),
|
adapter = Guice.createInjector(module, new Log4JLoggingModule())
|
||||||
ProductPackageClientLiveTest.CLOUD_SERVER_PACKAGE_NAME,
|
.getInstance(SoftLayerComputeServiceAdapter.class);
|
||||||
new SoftLayerComputeServiceAdapter.VirtualGuestHasLoginDetailsPresent(context.getApi()),60*60*1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -68,12 +65,12 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
|
||||||
@Test
|
@Test
|
||||||
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
|
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
|
||||||
String group = "foo";
|
String group = "foo";
|
||||||
String name = "node"+new Random().nextInt();
|
String name = "node" + new Random().nextInt();
|
||||||
Template template = computeContext.getComputeService().templateBuilder().build();
|
Template template = computeContext.getComputeService().templateBuilder().build();
|
||||||
|
|
||||||
// test passing custom options
|
// test passing custom options
|
||||||
template.getOptions().as(SoftLayerTemplateOptions.class).domainName("me.org");
|
template.getOptions().as(SoftLayerTemplateOptions.class).domainName("me.org");
|
||||||
|
|
||||||
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
Map<String, Credentials> credentialStore = Maps.newLinkedHashMap();
|
||||||
guest = adapter.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore);
|
guest = adapter.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore);
|
||||||
assertEquals(guest.getHostname(), name);
|
assertEquals(guest.getHostname(), name);
|
||||||
|
@ -86,8 +83,7 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doConnectViaSsh(VirtualGuest guest, Credentials creds) {
|
protected void doConnectViaSsh(VirtualGuest guest, Credentials creds) {
|
||||||
SshClient ssh = computeContext.utils().sshFactory()
|
SshClient ssh = computeContext.utils().sshFactory().create(new IPSocket(guest.getPrimaryIpAddress(), 22), creds);
|
||||||
.create(new IPSocket(guest.getPrimaryIpAddress(), 22), creds);
|
|
||||||
try {
|
try {
|
||||||
ssh.connect();
|
ssh.connect();
|
||||||
ExecResponse hello = ssh.exec("echo hello");
|
ExecResponse hello = ssh.exec("echo hello");
|
||||||
|
@ -103,15 +99,12 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testListHardwareProfiles() {
|
public void testListHardwareProfiles() {
|
||||||
Iterable<Set<ProductItem>> profiles = adapter.listHardwareProfiles();
|
Iterable<Iterable<ProductItem>> profiles = adapter.listHardwareProfiles();
|
||||||
assertFalse(Iterables.isEmpty(profiles));
|
assertFalse(Iterables.isEmpty(profiles));
|
||||||
|
|
||||||
for (Set<ProductItem> profile : profiles) {
|
for (Iterable<ProductItem> profile : profiles) {
|
||||||
// CPU, RAM and Volume
|
// CPU, RAM and Volume
|
||||||
assertEquals(profile.size(), 3);
|
assertEquals(Iterables.size(profile), 3);
|
||||||
ProductItem cpuItem = Iterables.getOnlyElement(Iterables.filter(profile, units("PRIVATE_CORE")));
|
|
||||||
ProductItem ramItem = Iterables.getOnlyElement(Iterables.filter(profile, categoryCode("ram")));
|
|
||||||
assertEquals(cpuItem.getCapacity(), ramItem.getCapacity());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,21 +19,31 @@
|
||||||
package org.jclouds.softlayer.compute;
|
package org.jclouds.softlayer.compute;
|
||||||
|
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||||
|
import static org.jclouds.compute.util.ComputeServiceUtils.getSpace;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
||||||
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.domain.OsFamilyVersion64Bit;
|
import org.jclouds.compute.domain.OsFamilyVersion64Bit;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.domain.Volume;
|
||||||
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -46,7 +56,7 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes
|
||||||
provider = "softlayer";
|
provider = "softlayer";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// allows us to break when a new os is added
|
// / allows us to break when a new os is added
|
||||||
@Override
|
@Override
|
||||||
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
|
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
|
||||||
return Predicates.not(new Predicate<OsFamilyVersion64Bit>() {
|
return Predicates.not(new Predicate<OsFamilyVersion64Bit>() {
|
||||||
|
@ -55,20 +65,20 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes
|
||||||
public boolean apply(OsFamilyVersion64Bit input) {
|
public boolean apply(OsFamilyVersion64Bit input) {
|
||||||
// For each os-type both 32- and 64-bit are supported.
|
// For each os-type both 32- and 64-bit are supported.
|
||||||
switch (input.family) {
|
switch (input.family) {
|
||||||
case UBUNTU:
|
case UBUNTU:
|
||||||
return input.version.equals("") || input.version.equals("10.04") || input.version.equals("8");
|
return input.version.equals("") || input.version.equals("10.04") || input.version.equals("8");
|
||||||
case DEBIAN:
|
case DEBIAN:
|
||||||
return input.version.equals("") || input.version.equals("5.0");
|
return input.version.equals("") || input.version.equals("5.0");
|
||||||
case FEDORA:
|
case FEDORA:
|
||||||
return input.version.equals("") || input.version.equals("13") || input.version.equals("15");
|
return input.version.equals("") || input.version.equals("13") || input.version.equals("15");
|
||||||
case RHEL:
|
case RHEL:
|
||||||
return input.version.equals("") || input.version.equals("5") || input.version.equals("6");
|
return input.version.equals("") || input.version.equals("5") || input.version.equals("6");
|
||||||
case CENTOS:
|
case CENTOS:
|
||||||
return input.version.equals("") || input.version.equals("5") || input.version.equals("6.0");
|
return input.version.equals("") || input.version.equals("5") || input.version.equals("6.0");
|
||||||
case WINDOWS:
|
case WINDOWS:
|
||||||
return input.version.equals("") || input.version.equals("2003") || input.version.equals("2008");
|
return input.version.equals("") || input.version.equals("2003") || input.version.equals("2008");
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,13 +91,134 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
assertEquals(getCores(defaultTemplate.getHardware()), 2.0d);
|
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||||
|
assertEquals(defaultTemplate.getHardware().getRam(), 1);
|
||||||
|
assertEquals(getSpace(defaultTemplate.getHardware()), 25.0d);
|
||||||
|
assertEquals(defaultTemplate.getHardware().getVolumes().get(0).getType(), Volume.Type.LOCAL);
|
||||||
// test that we bound the correct templateoptions in guice
|
// test that we bound the correct templateoptions in guice
|
||||||
assertEquals(defaultTemplate.getOptions().getClass(), SoftLayerTemplateOptions.class);
|
assertEquals(defaultTemplate.getOptions().getClass(), SoftLayerTemplateOptions.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTemplateBuilderFindsGigabitUplink() throws IOException {
|
||||||
|
ComputeServiceContext context = null;
|
||||||
|
try {
|
||||||
|
Properties overrides = setupProperties();
|
||||||
|
overrides.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED, "1000");
|
||||||
|
|
||||||
|
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
||||||
|
.<Module> of(new Log4JLoggingModule()), overrides);
|
||||||
|
|
||||||
|
// TODO add something to the template about port speed?
|
||||||
|
context.getComputeService().templateBuilder().build();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (context != null)
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTemplateBuilderFindsMegabitUplink() throws IOException {
|
||||||
|
ComputeServiceContext context = null;
|
||||||
|
try {
|
||||||
|
Properties overrides = setupProperties();
|
||||||
|
overrides.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED, "100");
|
||||||
|
|
||||||
|
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
||||||
|
.<Module> of(new Log4JLoggingModule()), overrides);
|
||||||
|
|
||||||
|
// TODO add something to the template about port speed?
|
||||||
|
context.getComputeService().templateBuilder().build();
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (context != null)
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBiggestTemplateBuilderWhenBootIsSAN() throws IOException {
|
||||||
|
ComputeServiceContext context = null;
|
||||||
|
try {
|
||||||
|
Properties overrides = setupProperties();
|
||||||
|
overrides.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE, "SAN");
|
||||||
|
|
||||||
|
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
||||||
|
.<Module> of(new Log4JLoggingModule()), overrides);
|
||||||
|
|
||||||
|
Template template = context.getComputeService().templateBuilder().biggest().build();
|
||||||
|
assertEquals(getCores(template.getHardware()), 16.0d);
|
||||||
|
assertEquals(template.getHardware().getRam(), 16);
|
||||||
|
assertEquals(getSpace(template.getHardware()), 100.0d);
|
||||||
|
assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.SAN);
|
||||||
|
} finally {
|
||||||
|
if (context != null)
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultTemplateBuilderWhenPrivateNetwork() throws IOException {
|
||||||
|
ComputeServiceContext context = null;
|
||||||
|
try {
|
||||||
|
Properties overrides = setupProperties();
|
||||||
|
overrides.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX, "Private [0-9]+ x ([.0-9]+) GHz Core[s]?");
|
||||||
|
|
||||||
|
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
||||||
|
.<Module> of(new Log4JLoggingModule()), overrides);
|
||||||
|
|
||||||
|
Template template = context.getComputeService().templateBuilder().build();
|
||||||
|
assertEquals(getCores(template.getHardware()), 1.0d);
|
||||||
|
assertEquals(template.getHardware().getRam(), 1);
|
||||||
|
assertEquals(getSpace(template.getHardware()), 25.0d);
|
||||||
|
assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.LOCAL);
|
||||||
|
} finally {
|
||||||
|
if (context != null)
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBiggestTemplateBuilderWhenPrivateNetwork() throws IOException {
|
||||||
|
ComputeServiceContext context = null;
|
||||||
|
try {
|
||||||
|
Properties overrides = setupProperties();
|
||||||
|
overrides.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX, "Private [0-9]+ x ([.0-9]+) GHz Core[s]?");
|
||||||
|
|
||||||
|
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
||||||
|
.<Module> of(new Log4JLoggingModule()), overrides);
|
||||||
|
|
||||||
|
Template template = context.getComputeService().templateBuilder().biggest().build();
|
||||||
|
assertEquals(getCores(template.getHardware()), 8.0d);
|
||||||
|
assertEquals(template.getHardware().getRam(), 16);
|
||||||
|
assertEquals(getSpace(template.getHardware()), 100.0d);
|
||||||
|
assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.LOCAL);
|
||||||
|
} finally {
|
||||||
|
if (context != null)
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void testFastestTemplateBuilder() throws IOException {
|
||||||
|
Template template = context.getComputeService().templateBuilder().fastest().build();
|
||||||
|
assertEquals(getCores(template.getHardware()), 16.0d);
|
||||||
|
assertEquals(template.getHardware().getRam(), 1);
|
||||||
|
assertEquals(getSpace(template.getHardware()), 25.0d);
|
||||||
|
assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.LOCAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBiggestTemplateBuilder() throws IOException {
|
||||||
|
Template template = context.getComputeService().templateBuilder().biggest().build();
|
||||||
|
assertEquals(getCores(template.getHardware()), 16.0d);
|
||||||
|
assertEquals(template.getHardware().getRam(), 16);
|
||||||
|
assertEquals(getSpace(template.getHardware()), 100.0d);
|
||||||
|
assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.LOCAL);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Set<String> getIso3166Codes() {
|
protected Set<String> getIso3166Codes() {
|
||||||
return ImmutableSet.<String> of("SG","US-CA","US-TX","US-VA","US-WA","US-TX");
|
return ImmutableSet.<String> of("SG", "US-CA", "US-TX", "US-VA", "US-WA", "US-TX");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,24 +18,30 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.compute.functions;
|
package org.jclouds.softlayer.compute.functions;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import static com.google.inject.name.Names.bindProperties;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import static org.jclouds.softlayer.compute.functions.ProductItemsToHardware.hardwareId;
|
||||||
|
import static org.testng.AssertJUnit.assertEquals;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Processor;
|
import org.jclouds.compute.domain.Processor;
|
||||||
import org.jclouds.compute.domain.Volume;
|
import org.jclouds.compute.domain.Volume;
|
||||||
|
import org.jclouds.softlayer.SoftLayerPropertiesBuilder;
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import org.jclouds.softlayer.domain.ProductItemCategory;
|
import org.jclouds.softlayer.domain.ProductItemCategory;
|
||||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import java.util.List;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import static org.jclouds.softlayer.compute.functions.ProductItemsToHardware.hardwareId;
|
import com.google.inject.AbstractModule;
|
||||||
import static org.testng.AssertJUnit.assertEquals;
|
import com.google.inject.Guice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@code ProductItemsToHardware}
|
* Tests {@code ProductItemsToHardware}
|
||||||
*
|
*
|
||||||
* @author Jason King
|
* @author Jason King
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit")
|
@Test(groups = "unit")
|
||||||
|
@ -48,46 +54,41 @@ public class ProductItemsToHardwareTest {
|
||||||
ProductItem item3 = ProductItem.builder().price(ProductItemPrice.builder().id(789).build()).build();
|
ProductItem item3 = ProductItem.builder().price(ProductItemPrice.builder().id(789).build()).build();
|
||||||
|
|
||||||
String id = hardwareId().apply(ImmutableList.of(item1, item2, item3));
|
String id = hardwareId().apply(ImmutableList.of(item1, item2, item3));
|
||||||
assertEquals("123,456,789",id);
|
assertEquals("123,456,789", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHardware() {
|
public void testHardware() {
|
||||||
ProductItem cpuItem = ProductItem.builder()
|
ProductItem cpuItem = ProductItem.builder().id(1).description("2 x 2.0 GHz Cores").units("PRIVATE_CORE")
|
||||||
.id(1)
|
.capacity(2F).price(ProductItemPrice.builder().id(123).build()).build();
|
||||||
.description("2 cores")
|
|
||||||
.units("PRIVATE_CORE")
|
|
||||||
.capacity(2F)
|
|
||||||
.price(ProductItemPrice.builder().id(123).build())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ProductItem ramItem = ProductItem.builder()
|
|
||||||
.id(2)
|
|
||||||
.description("2GB ram")
|
|
||||||
.capacity(2F)
|
|
||||||
.category(ProductItemCategory.builder().categoryCode("ram").build())
|
|
||||||
.price(ProductItemPrice.builder().id(456).build())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ProductItem volumeItem = ProductItem.builder()
|
ProductItem ramItem = ProductItem.builder().id(2).description("2GB ram").capacity(2F).category(
|
||||||
.id(3)
|
ProductItemCategory.builder().categoryCode("ram").build()).price(
|
||||||
.description("100 GB (SAN)")
|
ProductItemPrice.builder().id(456).build()).build();
|
||||||
.capacity(100F)
|
|
||||||
.price(ProductItemPrice.builder().id(789).build())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Hardware hardware = new ProductItemsToHardware().apply(ImmutableSet.of(cpuItem,ramItem,volumeItem));
|
ProductItem volumeItem = ProductItem.builder().id(3).description("100 GB (SAN)").capacity(100F).price(
|
||||||
|
ProductItemPrice.builder().id(789).build()).category(
|
||||||
|
ProductItemCategory.builder().categoryCode("guest_disk0").build()).build();
|
||||||
|
|
||||||
assertEquals("123,456,789",hardware.getId());
|
Hardware hardware = Guice.createInjector(new AbstractModule() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bindProperties(binder(), new SoftLayerPropertiesBuilder(new Properties()).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}).getInstance(ProductItemsToHardware.class).apply(ImmutableSet.of(cpuItem, ramItem, volumeItem));
|
||||||
|
|
||||||
|
assertEquals("123,456,789", hardware.getId());
|
||||||
|
|
||||||
List<? extends Processor> processors = hardware.getProcessors();
|
List<? extends Processor> processors = hardware.getProcessors();
|
||||||
assertEquals(1,processors.size());
|
assertEquals(1, processors.size());
|
||||||
assertEquals(2.0,processors.get(0).getCores());
|
assertEquals(2.0, processors.get(0).getCores());
|
||||||
|
|
||||||
assertEquals(2, hardware.getRam());
|
assertEquals(2, hardware.getRam());
|
||||||
|
|
||||||
List<? extends Volume> volumes = hardware.getVolumes();
|
List<? extends Volume> volumes = hardware.getVolumes();
|
||||||
assertEquals(1,volumes.size());
|
assertEquals(1, volumes.size());
|
||||||
assertEquals(100F,volumes.get(0).getSize());
|
assertEquals(100F, volumes.get(0).getSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,26 +18,40 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.compute.functions;
|
package org.jclouds.softlayer.compute.functions;
|
||||||
|
|
||||||
|
import static org.easymock.classextension.EasyMock.createNiceMock;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.*;
|
import org.jclouds.compute.domain.HardwareBuilder;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.ImageBuilder;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||||
|
import org.jclouds.compute.domain.NodeState;
|
||||||
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.softlayer.SoftLayerClient;
|
||||||
import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata.FindLocationForVirtualGuest;
|
import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata.FindLocationForVirtualGuest;
|
||||||
import org.jclouds.softlayer.domain.Password;
|
import org.jclouds.softlayer.domain.Password;
|
||||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
import org.jclouds.softlayer.parse.*;
|
import org.jclouds.softlayer.parse.ParseBadVirtualGuest;
|
||||||
|
import org.jclouds.softlayer.parse.ParseVirtualGuestHaltedTest;
|
||||||
|
import org.jclouds.softlayer.parse.ParseVirtualGuestPausedTest;
|
||||||
|
import org.jclouds.softlayer.parse.ParseVirtualGuestRunningTest;
|
||||||
|
import org.jclouds.softlayer.parse.ParseVirtualGuestWithNoPasswordTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -209,8 +223,9 @@ public class VirtualGuestToNodeMetadataTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class GetHardwareForVirtualGuestMock extends VirtualGuestToNodeMetadata.GetHardwareForVirtualGuest {
|
private static class GetHardwareForVirtualGuestMock extends VirtualGuestToNodeMetadata.GetHardwareForVirtualGuest {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public GetHardwareForVirtualGuestMock() {
|
public GetHardwareForVirtualGuestMock() {
|
||||||
super(null);
|
super(createNiceMock(SoftLayerClient.class), createNiceMock(Function.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,20 +19,36 @@
|
||||||
package org.jclouds.softlayer.features;
|
package org.jclouds.softlayer.features;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.inject.name.Names.bindProperties;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME;
|
||||||
|
import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.softlayer.SoftLayerAsyncClient;
|
import org.jclouds.softlayer.SoftLayerAsyncClient;
|
||||||
import org.jclouds.softlayer.SoftLayerClient;
|
import org.jclouds.softlayer.SoftLayerClient;
|
||||||
|
import org.jclouds.softlayer.SoftLayerPropertiesBuilder;
|
||||||
|
import org.jclouds.softlayer.compute.config.SoftLayerComputeServiceContextModule;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
import org.jclouds.softlayer.domain.ProductPackage;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
import org.testng.annotations.AfterGroups;
|
import org.testng.annotations.AfterGroups;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code SoftLayerClient}
|
* Tests behavior of {@code SoftLayerClient}
|
||||||
|
@ -44,16 +60,41 @@ public class BaseSoftLayerClientLiveTest {
|
||||||
|
|
||||||
protected RestContext<SoftLayerClient, SoftLayerAsyncClient> context;
|
protected RestContext<SoftLayerClient, SoftLayerAsyncClient> context;
|
||||||
protected ComputeServiceContext computeContext;
|
protected ComputeServiceContext computeContext;
|
||||||
|
protected Module module;
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
String identity = checkNotNull(System.getProperty("test.softlayer.identity"), "test.softlayer.identity");
|
String identity = checkNotNull(System.getProperty("test.softlayer.identity"), "test.softlayer.identity");
|
||||||
String credential = checkNotNull(System.getProperty("test.softlayer.credential"), "test.softlayer.credential");
|
String credential = checkNotNull(System.getProperty("test.softlayer.credential"), "test.softlayer.credential");
|
||||||
|
|
||||||
computeContext = new ComputeServiceContextFactory().createContext("softlayer", identity, credential,
|
computeContext = new ComputeServiceContextFactory().createContext("softlayer", identity, credential, ImmutableSet
|
||||||
ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
|
.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
|
||||||
context = computeContext.getProviderSpecificContext();
|
context = computeContext.getProviderSpecificContext();
|
||||||
|
module = new AbstractModule() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bindProperties(binder(), new SoftLayerPropertiesBuilder(new Properties()).build());
|
||||||
|
bind(SoftLayerClient.class).toInstance(context.getApi());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Memoized
|
||||||
|
public Supplier<ProductPackage> getProductPackage(SoftLayerClient client,
|
||||||
|
@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME) String virtualGuestPackageName) {
|
||||||
|
return new SoftLayerComputeServiceContextModule().getProductPackage(30, client, virtualGuestPackageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public Iterable<ProductItemPrice> prices(@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES) String prices) {
|
||||||
|
return new SoftLayerComputeServiceContextModule().prices(prices);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterGroups(groups = "live")
|
@AfterGroups(groups = "live")
|
||||||
|
|
|
@ -43,9 +43,11 @@ import static org.testng.Assert.*;
|
||||||
public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the package used for ordering virtual guests.
|
* Name of the package used for ordering virtual guests. For real this is passed in using the
|
||||||
* For real this is passed in using the property
|
* property
|
||||||
* @{code org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME}
|
*
|
||||||
|
* @{code org.jclouds.softlayer.reference.SoftLayerConstants.
|
||||||
|
* PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME}
|
||||||
*/
|
*/
|
||||||
public static final String CLOUD_SERVER_PACKAGE_NAME = "Cloud Server";
|
public static final String CLOUD_SERVER_PACKAGE_NAME = "Cloud Server";
|
||||||
|
|
||||||
|
@ -56,7 +58,8 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
accountClient = context.getApi().getAccountClient();
|
accountClient = context.getApi().getAccountClient();
|
||||||
|
|
||||||
// This is used several times, so cache to speed up the test.
|
// This is used several times, so cache to speed up the test.
|
||||||
cloudServerPackageId = Iterables.find(accountClient.getActivePackages(),named(CLOUD_SERVER_PACKAGE_NAME)).getId();
|
cloudServerPackageId = Iterables.find(accountClient.getActivePackages(), named(CLOUD_SERVER_PACKAGE_NAME))
|
||||||
|
.getId();
|
||||||
cloudServerProductPackage = client.getProductPackage(cloudServerPackageId);
|
cloudServerProductPackage = client.getProductPackage(cloudServerPackageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +110,7 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
assertEquals(datacenters.size(), expected.size());
|
assertEquals(datacenters.size(), expected.size());
|
||||||
assertTrue(datacenters.containsAll(expected));
|
assertTrue(datacenters.containsAll(expected));
|
||||||
|
|
||||||
for(Datacenter dataCenter: datacenters) {
|
for (Datacenter dataCenter : datacenters) {
|
||||||
Address address = dataCenter.getLocationAddress();
|
Address address = dataCenter.getLocationAddress();
|
||||||
assertNotNull(address);
|
assertNotNull(address);
|
||||||
checkAddress(address);
|
checkAddress(address);
|
||||||
|
@ -116,37 +119,42 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetOneGBRamPrice() {
|
public void testGetOneGBRamPrice() {
|
||||||
//Predicate p = Predicates.and(ProductItemPredicates.categoryCode("ram"),ProductItemPredicates.capacity(1.0f));
|
// Predicate p =
|
||||||
Iterable<ProductItem> ramItems = Iterables.filter(cloudServerProductPackage.getItems(),
|
// Predicates.and(ProductItemPredicates.categoryCode("ram"),ProductItemPredicates.capacity(1.0f));
|
||||||
Predicates.and(categoryCode("ram"), capacity(1.0f)));
|
Iterable<ProductItem> ramItems = Iterables.filter(cloudServerProductPackage.getItems(), Predicates.and(
|
||||||
|
categoryCode("ram"), capacity(1.0f)));
|
||||||
|
|
||||||
// capacity is key in GB (1Gb = 1.0f)
|
// capacity is key in GB (1Gb = 1.0f)
|
||||||
Map<Float, ProductItem> ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity());
|
Map<Float, ProductItem> ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity());
|
||||||
|
|
||||||
ProductItemPrice price = ProductItems.price().apply(ramToProductItem.get(1.0f));
|
ProductItemPrice price = ProductItems.price().apply(ramToProductItem.get(1.0f));
|
||||||
assert new Integer(1644).equals(price.getId());
|
assert new Integer(1644).equals(price.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetTwoCPUCoresPrice() {
|
public void testGetTwoCPUCoresPrice() {
|
||||||
// If use ProductItemPredicates.categoryCode("guest_core") get duplicate capacities (units = PRIVATE_CORE and N/A)
|
// If use ProductItemPredicates.categoryCode("guest_core") get duplicate capacities (units =
|
||||||
Iterable<ProductItem> cpuItems = Iterables.filter(cloudServerProductPackage.getItems(), Predicates.and(units("PRIVATE_CORE"), capacity(2.0f)));
|
// PRIVATE_CORE and N/A)
|
||||||
|
Iterable<ProductItem> cpuItems = Iterables.filter(cloudServerProductPackage.getItems(), Predicates.and(
|
||||||
|
units("PRIVATE_CORE"), capacity(2.0f)));
|
||||||
|
|
||||||
// number of cores is the key
|
// number of cores is the key
|
||||||
Map<Float, ProductItem> coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
|
Map<Float, ProductItem> coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
|
||||||
|
|
||||||
ProductItemPrice price = ProductItems.price().apply(coresToProductItem.get(2.0f));
|
ProductItemPrice price = ProductItems.price().apply(coresToProductItem.get(2.0f));
|
||||||
assert new Integer(1963).equals(price.getId());
|
assert new Integer(1963).equals(price.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetUbuntuPrice() {
|
public void testGetUbuntuPrice() {
|
||||||
Iterable<ProductItem> operatingSystems = Iterables.filter(cloudServerProductPackage.getItems(), categoryCode("os"));
|
Iterable<ProductItem> operatingSystems = Iterables.filter(cloudServerProductPackage.getItems(),
|
||||||
|
categoryCode("os"));
|
||||||
|
|
||||||
Map<String, ProductItem> osToProductItem = Maps.uniqueIndex(operatingSystems, ProductItems.description());
|
Map<String, ProductItem> osToProductItem = Maps.uniqueIndex(operatingSystems, ProductItems.description());
|
||||||
|
|
||||||
ProductItemPrice price = ProductItems.price().apply(osToProductItem.get("Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)"));
|
ProductItemPrice price = ProductItems.price().apply(
|
||||||
assert new Integer(1693).equals(price.getId());
|
osToProductItem.get("Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)"));
|
||||||
|
assert new Integer(1693).equals(price.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkProductItem(ProductItem item) {
|
private void checkProductItem(ProductItem item) {
|
||||||
|
@ -178,17 +186,17 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAddress(Address address) {
|
private void checkAddress(Address address) {
|
||||||
assert address.getId() >0 : address;
|
assert address.getId() > 0 : address;
|
||||||
assert address.getCountry() != null : address;
|
assert address.getCountry() != null : address;
|
||||||
if (!address.getCountry().equals("SG"))
|
if (!address.getCountry().equals("SG"))
|
||||||
assert address.getState() != null : address;
|
assert address.getState() != null : address;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkCategories(Set<ProductItemCategory> categories) {
|
private void checkCategories(Set<ProductItemCategory> categories) {
|
||||||
for( ProductItemCategory category: categories ) {
|
for (ProductItemCategory category : categories) {
|
||||||
assert category.getId() >0 : category;
|
assert category.getId() > 0 : category;
|
||||||
assert category.getName() != null : category;
|
assert category.getName() != null : category;
|
||||||
assert category.getCategoryCode() != null : category;
|
assert category.getCategoryCode() != null : category;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,23 +18,36 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.features;
|
package org.jclouds.softlayer.features;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.capacity;
|
||||||
import com.google.common.collect.Iterables;
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
|
||||||
import com.google.common.collect.Maps;
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
|
||||||
import com.google.common.collect.Sets;
|
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||||
import org.jclouds.softlayer.compute.functions.ProductItems;
|
import static org.testng.Assert.assertEquals;
|
||||||
import org.jclouds.softlayer.domain.*;
|
import static org.testng.Assert.assertNotNull;
|
||||||
import org.jclouds.softlayer.reference.SoftLayerConstants;
|
import static org.testng.Assert.assertTrue;
|
||||||
import org.testng.annotations.BeforeGroups;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
import org.jclouds.softlayer.compute.functions.ProductItems;
|
||||||
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import static org.testng.Assert.*;
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
import org.jclouds.softlayer.domain.ProductOrder;
|
||||||
|
import org.jclouds.softlayer.domain.ProductOrderReceipt;
|
||||||
|
import org.jclouds.softlayer.domain.ProductPackage;
|
||||||
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Key;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of {@code VirtualGuestClient}
|
* Tests behavior of {@code VirtualGuestClient}
|
||||||
|
@ -66,70 +79,69 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = false)
|
@Test(enabled = false, groups = "live")
|
||||||
public void testCancelAndPlaceOrder() {
|
public void testCancelAndPlaceOrder() {
|
||||||
|
|
||||||
// This method was not working needs testing out.
|
// This method was not working needs testing out.
|
||||||
|
|
||||||
// TODO: Should also check if there are active transactions before trying to cancel.
|
// TODO: Should also check if there are active transactions before trying to cancel.
|
||||||
// objectMask: virtualGuests.activeTransaction
|
// objectMask: virtualGuests.activeTransaction
|
||||||
for( VirtualGuest guest: client.listVirtualGuests()) {
|
for (VirtualGuest guest : client.listVirtualGuests()) {
|
||||||
if (guest.getHostname().startsWith(TEST_HOSTNAME_PREFIX)) {
|
if (guest.getHostname().startsWith(TEST_HOSTNAME_PREFIX)) {
|
||||||
if(guest.getBillingItemId()!=-1) {
|
if (guest.getBillingItemId() != -1) {
|
||||||
client.cancelService(guest.getBillingItemId());
|
client.cancelService(guest.getBillingItemId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pkgId = Iterables.find(context.getApi().getAccountClient().getActivePackages(),named(ProductPackageClientLiveTest.CLOUD_SERVER_PACKAGE_NAME)).getId();
|
int pkgId = Iterables.find(context.getApi().getAccountClient().getActivePackages(),
|
||||||
|
named(ProductPackageClientLiveTest.CLOUD_SERVER_PACKAGE_NAME)).getId();
|
||||||
ProductPackage productPackage = context.getApi().getProductPackageClient().getProductPackage(pkgId);
|
ProductPackage productPackage = context.getApi().getProductPackageClient().getProductPackage(pkgId);
|
||||||
|
|
||||||
Iterable<ProductItem> ramItems = Iterables.filter(productPackage.getItems(),
|
Iterable<ProductItem> ramItems = Iterables.filter(productPackage.getItems(), Predicates.and(categoryCode("ram"),
|
||||||
Predicates.and(categoryCode("ram"), capacity(2.0f)));
|
capacity(2.0f)));
|
||||||
|
|
||||||
Map<Float, ProductItem> ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity());
|
Map<Float, ProductItem> ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity());
|
||||||
|
|
||||||
ProductItemPrice ramPrice = ProductItems.price().apply(ramToProductItem.get(2.0f));
|
ProductItemPrice ramPrice = ProductItems.price().apply(ramToProductItem.get(2.0f));
|
||||||
|
|
||||||
Iterable<ProductItem> cpuItems = Iterables.filter(productPackage.getItems(), Predicates.and(units("PRIVATE_CORE"), capacity(2.0f)));
|
Iterable<ProductItem> cpuItems = Iterables.filter(productPackage.getItems(), Predicates.and(
|
||||||
Map<Float, ProductItem> coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
|
units("PRIVATE_CORE"), capacity(2.0f)));
|
||||||
|
Map<Float, ProductItem> coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
|
||||||
|
|
||||||
ProductItemPrice cpuPrice = ProductItems.price().apply(coresToProductItem.get(2.0f));
|
ProductItemPrice cpuPrice = ProductItems.price().apply(coresToProductItem.get(2.0f));
|
||||||
|
|
||||||
Iterable<ProductItem> operatingSystems = Iterables.filter(productPackage.getItems(), categoryCode("os"));
|
Iterable<ProductItem> operatingSystems = Iterables.filter(productPackage.getItems(), categoryCode("os"));
|
||||||
Map<String, ProductItem> osToProductItem = Maps.uniqueIndex(operatingSystems, ProductItems.description());
|
Map<String, ProductItem> osToProductItem = Maps.uniqueIndex(operatingSystems, ProductItems.description());
|
||||||
ProductItemPrice osPrice = ProductItems.price().apply(osToProductItem.get("Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)"));
|
ProductItemPrice osPrice = ProductItems.price().apply(
|
||||||
|
osToProductItem.get("Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)"));
|
||||||
|
|
||||||
Set<ProductItemPrice> prices = Sets.<ProductItemPrice>newLinkedHashSet();
|
Builder<ProductItemPrice> prices = ImmutableSet.<ProductItemPrice> builder();
|
||||||
prices.addAll(SoftLayerConstants.DEFAULT_VIRTUAL_GUEST_PRICES);
|
prices.addAll(Guice.createInjector(module).getInstance(Key.get(new TypeLiteral<Iterable<ProductItemPrice>>() {
|
||||||
prices.add(ramPrice);
|
})));
|
||||||
prices.add(cpuPrice);
|
prices.add(ramPrice);
|
||||||
prices.add(osPrice);
|
prices.add(cpuPrice);
|
||||||
|
prices.add(osPrice);
|
||||||
|
|
||||||
VirtualGuest guest = VirtualGuest.builder().domain("jclouds.org")
|
VirtualGuest guest = VirtualGuest.builder().domain("jclouds.org").hostname(
|
||||||
.hostname(TEST_HOSTNAME_PREFIX+new Random().nextInt())
|
TEST_HOSTNAME_PREFIX + new Random().nextInt()).build();
|
||||||
.build();
|
|
||||||
|
|
||||||
ProductOrder order = ProductOrder.builder()
|
ProductOrder order = ProductOrder.builder().packageId(pkgId).quantity(1).useHourlyPricing(true).prices(
|
||||||
.packageId(pkgId)
|
prices.build()).virtualGuest(guest).build();
|
||||||
.quantity(1)
|
|
||||||
.useHourlyPricing(true)
|
|
||||||
.prices(prices)
|
|
||||||
.virtualGuest(guest)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ProductOrderReceipt receipt = context.getApi().getVirtualGuestClient().orderVirtualGuest(order);
|
ProductOrderReceipt receipt = context.getApi().getVirtualGuestClient().orderVirtualGuest(order);
|
||||||
ProductOrder order2 = receipt.getOrderDetails();
|
ProductOrder order2 = receipt.getOrderDetails();
|
||||||
VirtualGuest result = Iterables.get(order2.getVirtualGuests(), 0);
|
VirtualGuest result = Iterables.get(order2.getVirtualGuests(), 0);
|
||||||
|
|
||||||
ProductOrder order3 = context.getApi().getVirtualGuestClient().getOrderTemplate(result.getId());
|
ProductOrder order3 = context.getApi().getVirtualGuestClient().getOrderTemplate(result.getId());
|
||||||
|
|
||||||
assertEquals(order.getPrices(),order3.getPrices());
|
assertEquals(order.getPrices(), order3.getPrices());
|
||||||
assertNotNull(receipt);
|
assertNotNull(receipt);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkVirtualGuest(VirtualGuest vg) {
|
private void checkVirtualGuest(VirtualGuest vg) {
|
||||||
if (vg.getBillingItemId()==-1) return;//Quotes and shutting down guests
|
if (vg.getBillingItemId() == -1)
|
||||||
|
return;// Quotes and shutting down guests
|
||||||
|
|
||||||
assert vg.getAccountId() > 0 : vg;
|
assert vg.getAccountId() > 0 : vg;
|
||||||
assert vg.getCreateDate() != null : vg;
|
assert vg.getCreateDate() != null : vg;
|
||||||
|
|
|
@ -18,15 +18,18 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.predicates;
|
package org.jclouds.softlayer.predicates;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import static org.testng.Assert.assertFalse;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.jclouds.softlayer.domain.ProductItem;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import org.jclouds.softlayer.domain.ProductItemCategory;
|
import org.jclouds.softlayer.domain.ProductItemCategory;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import static org.testng.Assert.assertFalse;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
@Test(sequential = true,groups = "unit")
|
@Test(singleThreaded = true, groups = "unit")
|
||||||
public class ProductItemPredicatesTest {
|
public class ProductItemPredicatesTest {
|
||||||
|
|
||||||
private ProductItemCategory ramCategory;
|
private ProductItemCategory ramCategory;
|
||||||
|
@ -37,66 +40,64 @@ public class ProductItemPredicatesTest {
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
ramCategory = ProductItemCategory.builder().id(1).categoryCode("ram").build();
|
ramCategory = ProductItemCategory.builder().id(1).categoryCode("ram").build();
|
||||||
|
|
||||||
item = ProductItem.builder().id(1)
|
item = ProductItem.builder().id(1).description("a test item").categories(ImmutableSet.of(ramCategory)).capacity(
|
||||||
.description("a test item")
|
2.0f).units("GB").build();
|
||||||
.categories(ImmutableSet.of(ramCategory))
|
|
||||||
.capacity(2.0f)
|
|
||||||
.units("GB")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
emptyItem = ProductItem.builder().id(1).build();
|
emptyItem = ProductItem.builder().id(1).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCategoryCodePresent() {
|
public void testCategoryCodePresent() {
|
||||||
assert ProductItemPredicates.categoryCode("ram").apply(item);
|
assert ProductItemPredicates.categoryCode("ram").apply(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCategoryCodePresentTwoCategories() {
|
public void testCategoryCodePresentTwoCategories() {
|
||||||
ProductItemCategory osCategory = ProductItemCategory.builder()
|
ProductItemCategory osCategory = ProductItemCategory.builder().id(2).categoryCode("os").build();
|
||||||
.id(2).categoryCode("os")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ProductItem item = ProductItem.builder()
|
ProductItem item = ProductItem.builder().categories(ImmutableSet.of(ramCategory, osCategory)).build();
|
||||||
.categories(ImmutableSet.of(ramCategory, osCategory))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assert ProductItemPredicates.categoryCode("ram").apply(item);
|
assert ProductItemPredicates.categoryCode("ram").apply(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCategoryCodeMissing() {
|
public void testCategoryCodeMissing() {
|
||||||
assertFalse(ProductItemPredicates.categoryCode("missing").apply(emptyItem));
|
assertFalse(ProductItemPredicates.categoryCode("missing").apply(emptyItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCategoryCodeMatches() {
|
||||||
|
ProductItemPredicates.categoryCodeMatches(Pattern.compile("ra.*")).apply(item);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCapacityPresent() {
|
|
||||||
assert ProductItemPredicates.capacity(2.0f).apply(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCapacityMissing() {
|
public void testCapacityPresent() {
|
||||||
assertFalse(ProductItemPredicates.capacity(1.0f).apply(item));
|
assert ProductItemPredicates.capacity(2.0f).apply(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnitsPresent() {
|
public void testCapacityMissing() {
|
||||||
assert ProductItemPredicates.units("GB").apply(item);
|
assertFalse(ProductItemPredicates.capacity(1.0f).apply(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnitsMissing() {
|
public void testUnitsPresent() {
|
||||||
assertFalse(ProductItemPredicates.units("Kg").apply(item));
|
assert ProductItemPredicates.units("GB").apply(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMatchesRegex() {
|
public void testUnitsMissing() {
|
||||||
assert ProductItemPredicates.matches(".*test.*").apply(item);
|
assertFalse(ProductItemPredicates.units("Kg").apply(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoMatchRegex() {
|
public void testMatchesRegex() {
|
||||||
assertFalse(ProductItemPredicates.matches("no match").apply(item));
|
assert ProductItemPredicates.matches(Pattern.compile(".*test.*")).apply(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNoMatchRegex() {
|
||||||
|
assertFalse(ProductItemPredicates.matches(Pattern.compile("no match")).apply(item));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue