mirror of https://github.com/apache/jclouds.git
Merge pull request #78 from jsonking/master
Issue 158: Functions for Image and Hardware. Implemented SoftLayerComputeServiceAdapter listImages/listHardwareProfiles methods
This commit is contained in:
commit
94c74a7424
|
@ -18,34 +18,36 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.compute.config;
|
package org.jclouds.softlayer.compute.config;
|
||||||
|
|
||||||
import java.util.Set;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
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;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
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.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;
|
||||||
import org.jclouds.softlayer.compute.functions.ProductItemPriceToImage;
|
import org.jclouds.softlayer.compute.functions.ProductItemToImage;
|
||||||
import org.jclouds.softlayer.compute.functions.ProductItemPricesToHardware;
|
import org.jclouds.softlayer.compute.functions.ProductItemsToHardware;
|
||||||
import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata;
|
import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata;
|
||||||
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.ProductItemPrice;
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
import org.jclouds.softlayer.domain.VirtualGuest;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import java.util.Set;
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.inject.TypeLiteral;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class SoftLayerComputeServiceContextModule extends
|
public class SoftLayerComputeServiceContextModule extends
|
||||||
ComputeServiceAdapterContextModule<SoftLayerClient, SoftLayerAsyncClient, VirtualGuest, Set<ProductItemPrice>, ProductItemPrice, Datacenter> {
|
ComputeServiceAdapterContextModule<SoftLayerClient, SoftLayerAsyncClient, VirtualGuest, Set<ProductItem>, ProductItem, Datacenter> {
|
||||||
|
|
||||||
public SoftLayerComputeServiceContextModule() {
|
public SoftLayerComputeServiceContextModule() {
|
||||||
super(SoftLayerClient.class, SoftLayerAsyncClient.class);
|
super(SoftLayerClient.class, SoftLayerAsyncClient.class);
|
||||||
|
@ -54,17 +56,25 @@ public class SoftLayerComputeServiceContextModule extends
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
bind(new TypeLiteral<ComputeServiceAdapter<VirtualGuest, Set<ProductItemPrice>, ProductItemPrice, Datacenter>>() {
|
bind(new TypeLiteral<ComputeServiceAdapter<VirtualGuest, Set<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<ProductItemPrice, org.jclouds.compute.domain.Image>>() {
|
bind(new TypeLiteral<Function<ProductItem, org.jclouds.compute.domain.Image>>() {})
|
||||||
}).to(ProductItemPriceToImage.class);
|
.to(ProductItemToImage.class);
|
||||||
bind(new TypeLiteral<Function<Set<ProductItemPrice>, org.jclouds.compute.domain.Hardware>>() {
|
bind(new TypeLiteral<Function<Set<ProductItem>, org.jclouds.compute.domain.Hardware>>() {})
|
||||||
}).to(ProductItemPricesToHardware.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||||
|
return template.osFamily(OsFamily.UBUNTU)
|
||||||
|
.osVersionMatches("1[10].[10][04]")
|
||||||
|
.os64Bit(true)
|
||||||
|
.osDescriptionMatches(".*Minimal Install.*")
|
||||||
|
.minCores(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,61 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.softlayer.compute.functions;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.compute.domain.Image;
|
|
||||||
import org.jclouds.compute.domain.ImageBuilder;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class ProductItemPriceToImage implements Function<ProductItemPrice, Image> {
|
|
||||||
@Resource
|
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Image apply(ProductItemPrice from) {
|
|
||||||
|
|
||||||
ImageBuilder builder = new ImageBuilder();
|
|
||||||
//TODO
|
|
||||||
// builder.ids(from.id + "");
|
|
||||||
// builder.name(from.name);
|
|
||||||
// builder.description(from.name);
|
|
||||||
//
|
|
||||||
// OsFamily family = null;
|
|
||||||
// try {
|
|
||||||
// family = OsFamily.fromValue(from.name);
|
|
||||||
// builder.operatingSystem(new OperatingSystem.Builder().name(from.name).family(family).build());
|
|
||||||
// } catch (IllegalArgumentException e) {
|
|
||||||
// logger.debug("<< didn't match os(%s)", from);
|
|
||||||
// }
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.softlayer.compute.functions;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
|
||||||
import org.jclouds.compute.domain.HardwareBuilder;
|
|
||||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class ProductItemPricesToHardware implements Function<Set<ProductItemPrice>, Hardware> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Hardware apply(Set<ProductItemPrice> from) {
|
|
||||||
HardwareBuilder builder = new HardwareBuilder();
|
|
||||||
// builder.ids(from.id + "");
|
|
||||||
// builder.name(from.name);
|
|
||||||
// builder.processors(ImmutableList.of(new Processor(from.cores, 1.0)));
|
|
||||||
// builder.ram(from.ram);
|
|
||||||
// builder.volumes(ImmutableList.<Volume> of(new VolumeImpl(from.disk, true, false)));
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.softlayer.compute.functions;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.ImageBuilder;
|
||||||
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jason King
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ProductItemToImage implements Function<ProductItem, Image> {
|
||||||
|
|
||||||
|
/** Pattern to capture the number of bits e.g. "a (32 bit) os" */
|
||||||
|
private static final Pattern OS_BITS_PATTERN = Pattern.compile(".*\\((\\d+) ?bit\\).*");
|
||||||
|
|
||||||
|
private static final String CENTOS = "CentOS";
|
||||||
|
private static final String DEBIAN = "Debian GNU/Linux";
|
||||||
|
private static final String FEDORA = "Fedora Release";
|
||||||
|
private static final String RHEL = "Red Hat Enterprise Linux";
|
||||||
|
private static final String UBUNTU = "Ubuntu Linux";
|
||||||
|
private static final String WINDOWS = "Windows Server";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Image apply(ProductItem productItem) {
|
||||||
|
checkNotNull(productItem,"productItem");
|
||||||
|
|
||||||
|
OsFamily family = osFamily().apply(productItem);
|
||||||
|
Integer bits = osBits().apply(productItem);
|
||||||
|
OperatingSystem os = OperatingSystem.builder()
|
||||||
|
.description(productItem.getDescription())
|
||||||
|
.family(family)
|
||||||
|
.version(osVersion().apply(productItem))
|
||||||
|
.is64Bit(bits.equals(64))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return new ImageBuilder()
|
||||||
|
.id(imageId().apply(productItem))
|
||||||
|
.description(productItem.getDescription())
|
||||||
|
.operatingSystem(os)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the item description to determine the OSFamily
|
||||||
|
* @return the @see OsFamily or OsFamily.UNRECOGNIZED
|
||||||
|
*/
|
||||||
|
public static Function<ProductItem,OsFamily> osFamily() {
|
||||||
|
return new Function<ProductItem,OsFamily>() {
|
||||||
|
@Override
|
||||||
|
public OsFamily apply(ProductItem productItem) {
|
||||||
|
checkNotNull(productItem,"productItem");
|
||||||
|
|
||||||
|
final String description = productItem.getDescription();
|
||||||
|
if(description.startsWith(CENTOS)) return OsFamily.CENTOS;
|
||||||
|
else if(description.startsWith(DEBIAN)) return OsFamily.DEBIAN;
|
||||||
|
else if(description.startsWith(FEDORA)) return OsFamily.FEDORA;
|
||||||
|
else if(description.startsWith(RHEL)) return OsFamily.RHEL;
|
||||||
|
else if(description.startsWith(UBUNTU)) return OsFamily.UBUNTU;
|
||||||
|
else if(description.startsWith(WINDOWS)) return OsFamily.WINDOWS;
|
||||||
|
return OsFamily.UNRECOGNIZED;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the item description to determine the os version
|
||||||
|
* @return the version
|
||||||
|
* @throws java.util.NoSuchElementException if the version cannot be determined
|
||||||
|
*/
|
||||||
|
public static Function<ProductItem,String> osVersion() {
|
||||||
|
return new Function<ProductItem,String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(ProductItem productItem) {
|
||||||
|
checkNotNull(productItem,"productItem");
|
||||||
|
|
||||||
|
final String description = productItem.getDescription();
|
||||||
|
OsFamily family = osFamily().apply(productItem);
|
||||||
|
if (family.equals(OsFamily.CENTOS)) return parseVersion(description, CENTOS);
|
||||||
|
else if(family.equals(OsFamily.DEBIAN)) return parseVersion(description, DEBIAN);
|
||||||
|
else if(family.equals(OsFamily.FEDORA)) return parseVersion(description, FEDORA);
|
||||||
|
else if(family.equals(OsFamily.RHEL)) return parseVersion(description, RHEL);
|
||||||
|
else if(family.equals(OsFamily.UBUNTU)) return parseVersion(description, UBUNTU);
|
||||||
|
else if(family.equals(OsFamily.WINDOWS)) return parseVersion(description, WINDOWS);
|
||||||
|
else throw new NoSuchElementException("No os version for item:"+productItem);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String parseVersion(String description, String os) {
|
||||||
|
String noOsName = description.replaceFirst(os,"").trim();
|
||||||
|
return noOsName.split(" ")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the item description to determine the number of OS bits
|
||||||
|
* Expects the number to be in parenthesis and to contain the word "bit".
|
||||||
|
* The following return 64: "A (64 bit) OS", "A (64bit) OS"
|
||||||
|
* @return the number of bits
|
||||||
|
* @throws java.util.NoSuchElementException if the number of bits cannot be determined
|
||||||
|
*/
|
||||||
|
public static Function<ProductItem,Integer> osBits() {
|
||||||
|
return new Function<ProductItem,Integer>() {
|
||||||
|
@Override
|
||||||
|
public Integer apply(ProductItem productItem) {
|
||||||
|
checkNotNull(productItem,"productItem");
|
||||||
|
|
||||||
|
Matcher m = OS_BITS_PATTERN.matcher(productItem.getDescription());
|
||||||
|
if (m.matches()) {
|
||||||
|
return Integer.parseInt(m.group(1));
|
||||||
|
} else {
|
||||||
|
throw new NoSuchElementException("Cannot determine os-bits for item:"+productItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an id for an Image.
|
||||||
|
* @return the generated id
|
||||||
|
*/
|
||||||
|
public static Function<ProductItem,String> imageId() {
|
||||||
|
return new Function<ProductItem,String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(ProductItem productItem) {
|
||||||
|
checkNotNull(productItem,"productItem");
|
||||||
|
ProductItemPrice price = ProductItems.price().apply(productItem);
|
||||||
|
return ""+price.getId();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.softlayer.compute.functions;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
import org.jclouds.compute.domain.HardwareBuilder;
|
||||||
|
import org.jclouds.compute.domain.Processor;
|
||||||
|
import org.jclouds.compute.domain.Volume;
|
||||||
|
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.ProductItemPrice;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
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.
|
||||||
|
* All cores have a speed of 2.0Ghz
|
||||||
|
* The Hardware Id will be a comma separated list containing the price ids:
|
||||||
|
* cpus,ram,volume
|
||||||
|
*
|
||||||
|
* @author Jason King
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ProductItemsToHardware implements Function<Set<ProductItem>, Hardware> {
|
||||||
|
|
||||||
|
private static final double CORE_SPEED = 2.0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Hardware apply(Set<ProductItem> items) {
|
||||||
|
|
||||||
|
ProductItem coresItem = getOnlyElement(filter(items, units("PRIVATE_CORE")));
|
||||||
|
ProductItem ramItem = getOnlyElement(filter(items, categoryCode("ram")));
|
||||||
|
ProductItem volumeItem = getOnlyElement(filter(items, matches(SoftLayerComputeServiceAdapter.SAN_DESCRIPTION_REGEX)));
|
||||||
|
|
||||||
|
final String hardwareId = hardwareId().apply(ImmutableList.of(coresItem, ramItem, volumeItem));
|
||||||
|
final double cores = ProductItems.capacity().apply(coresItem).doubleValue();
|
||||||
|
final int ram = ProductItems.capacity().apply(ramItem).intValue();
|
||||||
|
final float volumeSize = ProductItems.capacity().apply(volumeItem);
|
||||||
|
|
||||||
|
return new HardwareBuilder()
|
||||||
|
.id(hardwareId)
|
||||||
|
.processors(ImmutableList.of(new Processor(cores, CORE_SPEED)))
|
||||||
|
.ram(ram)
|
||||||
|
.volumes(ImmutableList.<Volume> of(new VolumeImpl(volumeSize, true, false)))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a hardwareId based on the priceId's of the items in the list
|
||||||
|
* @return comma separated list of priceid's
|
||||||
|
*/
|
||||||
|
public static Function<List<ProductItem>,String> hardwareId() {
|
||||||
|
return new Function<List<ProductItem>,String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(List<ProductItem> productItems) {
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for(ProductItem item:productItems) {
|
||||||
|
ProductItemPrice price = ProductItems.price().apply(item);
|
||||||
|
builder.append(price.getId())
|
||||||
|
.append(",");
|
||||||
|
}
|
||||||
|
return builder.toString().substring(0,builder.lastIndexOf(","));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,12 +49,11 @@ import com.google.common.collect.ImmutableSet;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMetadata> {
|
public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMetadata> {
|
||||||
|
|
||||||
//TODO: There may be more states than this.
|
|
||||||
public static final Map<VirtualGuest.State, NodeState> serverStateToNodeState = ImmutableMap
|
public static final Map<VirtualGuest.State, NodeState> serverStateToNodeState = ImmutableMap
|
||||||
.<VirtualGuest.State, NodeState> builder()
|
.<VirtualGuest.State, NodeState> builder()
|
||||||
.put(VirtualGuest.State.RUNNING, NodeState.RUNNING)
|
|
||||||
.put(VirtualGuest.State.PAUSED, NodeState.SUSPENDED)
|
|
||||||
.put(VirtualGuest.State.HALTED, NodeState.PENDING)
|
.put(VirtualGuest.State.HALTED, NodeState.PENDING)
|
||||||
|
.put(VirtualGuest.State.PAUSED, NodeState.SUSPENDED)
|
||||||
|
.put(VirtualGuest.State.RUNNING, NodeState.RUNNING)
|
||||||
.put(VirtualGuest.State.UNRECOGNIZED, NodeState.UNRECOGNIZED)
|
.put(VirtualGuest.State.UNRECOGNIZED, NodeState.UNRECOGNIZED)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
@ -18,29 +18,31 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.softlayer.compute.strategy;
|
package org.jclouds.softlayer.compute.strategy;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import java.util.Map;
|
import com.google.common.collect.Iterables;
|
||||||
import java.util.Set;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.compute.ComputeService;
|
import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.compute.ComputeServiceAdapter;
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
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.softlayer.SoftLayerClient;
|
import org.jclouds.softlayer.SoftLayerClient;
|
||||||
import org.jclouds.softlayer.domain.Datacenter;
|
import org.jclouds.softlayer.compute.functions.ProductItems;
|
||||||
import org.jclouds.softlayer.domain.ProductItemPrice;
|
import org.jclouds.softlayer.domain.*;
|
||||||
import org.jclouds.softlayer.domain.ProductPackage;
|
import org.jclouds.softlayer.features.AccountClient;
|
||||||
import org.jclouds.softlayer.domain.VirtualGuest;
|
import org.jclouds.softlayer.features.ProductPackageClient;
|
||||||
import org.jclouds.softlayer.predicates.ProductPackagePredicates;
|
|
||||||
import org.jclouds.softlayer.reference.SoftLayerConstants;
|
import org.jclouds.softlayer.reference.SoftLayerConstants;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import javax.inject.Inject;
|
||||||
import com.google.common.collect.Iterables;
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds
|
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds
|
||||||
|
@ -49,7 +51,12 @@ import com.google.common.collect.Iterables;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class SoftLayerComputeServiceAdapter implements
|
public class SoftLayerComputeServiceAdapter implements
|
||||||
ComputeServiceAdapter<VirtualGuest, Set<ProductItemPrice>, ProductItemPrice, Datacenter> {
|
ComputeServiceAdapter<VirtualGuest, Set<ProductItem>, ProductItem, Datacenter> {
|
||||||
|
|
||||||
|
public static final String SAN_DESCRIPTION_REGEX=".*GB \\(SAN\\).*";
|
||||||
|
//TODO: Better to pass this in as a property like virtualGuestPackageName?
|
||||||
|
private static final Float BOOT_VOLUME_CAPACITY = 100F;
|
||||||
|
|
||||||
private final SoftLayerClient client;
|
private final SoftLayerClient client;
|
||||||
private final String virtualGuestPackageName;
|
private final String virtualGuestPackageName;
|
||||||
|
|
||||||
|
@ -76,15 +83,37 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Set<ProductItemPrice>> listHardwareProfiles() {
|
public Iterable<Set<ProductItem>> listHardwareProfiles() {
|
||||||
// TODO: get the set of product item prices corresponding to the hardware profiles
|
ProductPackage productPackage = getProductPackage();
|
||||||
return ImmutableSet.of();
|
Set<ProductItem> items = productPackage.getItems();
|
||||||
|
|
||||||
|
Iterable<ProductItem> cpuItems = Iterables.filter(items, units("PRIVATE_CORE"));
|
||||||
|
Iterable<ProductItem> ramItems = Iterables.filter(items,categoryCode("ram"));
|
||||||
|
Iterable<ProductItem> sanItems = Iterables.filter(items, Predicates.and(matches(SAN_DESCRIPTION_REGEX),categoryCode("one_time_charge")));
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<ProductItemPrice> listImages() {
|
public Iterable<ProductItem> listImages() {
|
||||||
// TODO: get the list of product item prices corresponding to images
|
return Iterables.filter(getProductPackage().getItems(), categoryCode("os"));
|
||||||
return ImmutableSet.of();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -94,10 +123,15 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Datacenter> listLocations() {
|
public Iterable<Datacenter> listLocations() {
|
||||||
// TODO we should be able to specify a filter that gets the datacenters here.
|
return getProductPackage().getDatacenters();
|
||||||
ProductPackage virtualGuestPackage = Iterables.find(client.getAccountClient().getActivePackages(),
|
}
|
||||||
ProductPackagePredicates.named(virtualGuestPackageName));
|
|
||||||
return client.getProductPackageClient().getProductPackage(virtualGuestPackage.getId()).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
|
||||||
|
@ -108,8 +142,13 @@ public class SoftLayerComputeServiceAdapter implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroyNode(String id) {
|
public void destroyNode(String id) {
|
||||||
// TODO
|
VirtualGuest guest = getNode(id);
|
||||||
// client.getVirtualGuestClient().destroyVirtualGuest(Long.parseLong(id));
|
if(guest==null) return;
|
||||||
|
|
||||||
|
BillingItemVirtualGuest billingItem = guest.getBillingItem();
|
||||||
|
if (billingItem==null) return;
|
||||||
|
|
||||||
|
client.getVirtualGuestClient().cancelService(billingItem.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -205,14 +205,13 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TBD: These states come from the powerState field. i.e.
|
* These states come from the powerState field. i.e.
|
||||||
* https://api.softlayer.com/rest/v3/SoftLayer_Account/getVirtualGuests/{id}?objectMask=powerState
|
* https://api.softlayer.com/rest/v3/SoftLayer_Account/getVirtualGuests/{id}?objectMask=powerState
|
||||||
*/
|
*/
|
||||||
public static enum State {
|
public static enum State {
|
||||||
//ACTIVE, // Get this from https://api.softlayer.com/rest/v3/SoftLayer_Virtual_Guest/{id}/getStatus
|
HALTED,
|
||||||
PAUSED,
|
PAUSED,
|
||||||
RUNNING,
|
RUNNING,
|
||||||
HALTED,
|
|
||||||
UNRECOGNIZED;
|
UNRECOGNIZED;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -22,6 +22,8 @@ import com.google.common.base.Predicate;
|
||||||
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 java.util.regex.Pattern;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class ProductItemPredicates {
|
public class ProductItemPredicates {
|
||||||
|
@ -75,7 +77,6 @@ public class ProductItemPredicates {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if the ProductItem has the required units.
|
* Tests if the ProductItem has the required units.
|
||||||
* TODO Write test method
|
|
||||||
* @param units
|
* @param units
|
||||||
* @return true if it does, otherwise false.
|
* @return true if it does, otherwise false.
|
||||||
*/
|
*/
|
||||||
|
@ -94,4 +95,28 @@ public class ProductItemPredicates {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if the ProductItem's description matches the supplied regular expression.
|
||||||
|
* @param regex a regular expression to match against.
|
||||||
|
* @return true if it does, otherwise false.
|
||||||
|
* @throws java.util.regex.PatternSyntaxException if the regex is invalid
|
||||||
|
*/
|
||||||
|
public static Predicate<ProductItem> matches(final String regex) {
|
||||||
|
checkNotNull(regex, "regex cannot be null");
|
||||||
|
final Pattern PATTERN = Pattern.compile(regex);
|
||||||
|
|
||||||
|
return new Predicate<ProductItem>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(ProductItem productItem) {
|
||||||
|
checkNotNull(productItem, "productItem cannot ne null");
|
||||||
|
return PATTERN.matcher(productItem.getDescription()).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "regex("+regex+")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,6 @@ public interface SoftLayerConstants {
|
||||||
*/
|
*/
|
||||||
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";
|
||||||
|
|
||||||
/**
|
|
||||||
* Name of the package used for ordering virtual guests.
|
|
||||||
*/
|
|
||||||
public static final String CLOUD_SERVER_PACKAGE_NAME = "Cloud Server";
|
|
||||||
|
|
||||||
public static final Set<ProductItemPrice> DEFAULT_VIRTUAL_GUEST_PRICES = ImmutableSet.<ProductItemPrice>builder()
|
public static final Set<ProductItemPrice> DEFAULT_VIRTUAL_GUEST_PRICES = ImmutableSet.<ProductItemPrice>builder()
|
||||||
.add(ProductItemPrice.builder().id(1639).build()) // 100 GB (SAN)
|
.add(ProductItemPrice.builder().id(1639).build()) // 100 GB (SAN)
|
||||||
.add(ProductItemPrice.builder().id(21).build()) // 1 IP Address
|
.add(ProductItemPrice.builder().id(21).build()) // 1 IP Address
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.softlayer.compute;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
|
||||||
|
import org.jclouds.softlayer.domain.Datacenter;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
|
import org.jclouds.softlayer.features.BaseSoftLayerClientLiveTest;
|
||||||
|
import org.jclouds.softlayer.features.ProductPackageClientLiveTest;
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
|
||||||
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.AssertJUnit.assertEquals;
|
||||||
|
|
||||||
|
@Test(groups = "live", testName = "SoftLayerComputeServiceAdapterLiveTest")
|
||||||
|
public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
|
|
||||||
|
private SoftLayerComputeServiceAdapter adapter;
|
||||||
|
|
||||||
|
@BeforeGroups(groups = { "live" })
|
||||||
|
public void setupClient() {
|
||||||
|
super.setupClient();
|
||||||
|
adapter = new SoftLayerComputeServiceAdapter(context.getApi(), ProductPackageClientLiveTest.CLOUD_SERVER_PACKAGE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListLocations() {
|
||||||
|
assertFalse(Iterables.isEmpty(adapter.listLocations()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testListHardwareProfiles() {
|
||||||
|
Iterable<Set<ProductItem>> profiles = adapter.listHardwareProfiles();
|
||||||
|
assertFalse(Iterables.isEmpty(profiles));
|
||||||
|
|
||||||
|
for( Set<ProductItem> profile: profiles) {
|
||||||
|
// CPU, RAM and Volume
|
||||||
|
assertEquals(profile.size(), 3);
|
||||||
|
ProductItem cpuItem = Iterables.getOnlyElement(Iterables.filter(profile, units("PRIVATE_CORE")));
|
||||||
|
ProductItem ramItem = Iterables.getOnlyElement(Iterables.filter(profile,categoryCode("ram")));
|
||||||
|
Assert.assertEquals(cpuItem.getCapacity(),ramItem.getCapacity());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.softlayer.compute;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.OsFamilyVersion64Bit;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jason King
|
||||||
|
*/
|
||||||
|
@Test(groups = "live")
|
||||||
|
public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||||
|
|
||||||
|
public SoftLayerTemplateBuilderLiveTest() {
|
||||||
|
provider = "softlayer";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// allows us to break when a new os is added
|
||||||
|
@Override
|
||||||
|
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
|
||||||
|
return Predicates.not(new Predicate<OsFamilyVersion64Bit>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(OsFamilyVersion64Bit input) {
|
||||||
|
// For each os-type both 32- and 64-bit are supported.
|
||||||
|
switch (input.family) {
|
||||||
|
case UBUNTU:
|
||||||
|
return !(input.version.equals("10.04") || input.version.equals("8"));
|
||||||
|
case DEBIAN:
|
||||||
|
return !(input.version.equals("5.0"));
|
||||||
|
case FEDORA:
|
||||||
|
return !(input.version.equals("13") || input.version.equals("15"));
|
||||||
|
case RHEL:
|
||||||
|
return !(input.version.equals("5") || input.version.equals("6"));
|
||||||
|
case CENTOS:
|
||||||
|
return !(input.version.equals("5") || input.version.equals("6.0"));
|
||||||
|
case WINDOWS:
|
||||||
|
return !(input.version.equals("2003") || input.version.equals("2008"));
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultTemplateBuilder() throws IOException {
|
||||||
|
Template defaultTemplate = context.getComputeService().templateBuilder().build();
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
|
assertEquals(getCores(defaultTemplate.getHardware()), 2.0d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Set<String> getIso3166Codes() {
|
||||||
|
return ImmutableSet.<String> of("US-IL", "US-TX", "US-MO");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
package org.jclouds.softlayer.compute.functions;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import static org.jclouds.softlayer.compute.functions.ProductItemToImage.*;
|
||||||
|
import static org.testng.AssertJUnit.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests {@code ProductItemToImage}
|
||||||
|
*
|
||||||
|
* @author Jason King
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ProductItemToImageTest {
|
||||||
|
// Operating Systems available SEPT 2011
|
||||||
|
private static final List<String> operatingSystems = Arrays.asList(
|
||||||
|
"CentOS 5 - LAMP Install (32 bit)",
|
||||||
|
"CentOS 5 - LAMP Install (64 bit)",
|
||||||
|
"CentOS 5 - Minimal Install (32 bit)",
|
||||||
|
"CentOS 5 - Minimal Install (64 bit)",
|
||||||
|
"CentOS 6.0 - LAMP Install (32 bit)",
|
||||||
|
"CentOS 6.0 - LAMP Install (64 bit)",
|
||||||
|
"CentOS 6.0 - Minimal Install (32 bit)",
|
||||||
|
"CentOS 6.0 - Minimal Install (64 bit)",
|
||||||
|
"Debian GNU/Linux 5.0 Lenny/Stable - LAMP Install (32 bit)",
|
||||||
|
"Debian GNU/Linux 5.0 Lenny/Stable - LAMP Install (64 bit)",
|
||||||
|
"Debian GNU/Linux 5.0 Lenny/Stable - Minimal Install (32 bit)",
|
||||||
|
"Debian GNU/Linux 5.0 Lenny/Stable - Minimal Install (64 bit)",
|
||||||
|
"Fedora Release 13 (32bit) - LAMP Install",
|
||||||
|
"Fedora Release 13 (32bit) - Minimal Install",
|
||||||
|
"Fedora Release 13 (64bit) - LAMP Install",
|
||||||
|
"Fedora Release 13 (64bit) - Minimal Install",
|
||||||
|
"Fedora Release 15 (32bit) - LAMP Install",
|
||||||
|
"Fedora Release 15 (32bit) - Minimal Install",
|
||||||
|
"Fedora Release 15 (64bit) - LAMP Install",
|
||||||
|
"Fedora Release 15 (64bit) - Minimal Install",
|
||||||
|
"Red Hat Enterprise Linux 5 - LAMP Install (32 bit)",
|
||||||
|
"Red Hat Enterprise Linux 5 - LAMP Install (64 bit)",
|
||||||
|
"Red Hat Enterprise Linux 5 - Minimal Install (64 bit)",
|
||||||
|
"Red Hat Enterprise Linux 6 - LAMP Install (32 bit)",
|
||||||
|
"Red Hat Enterprise Linux 6 - LAMP Install (64 bit)",
|
||||||
|
"Red Hat Enterprise Linux 6 - Minimal Install (32 bit)",
|
||||||
|
"Red Hat Enterprise Linux 6 - Minimal Install (64 bit)",
|
||||||
|
"Ubuntu Linux 10.04 LTS Lucid Lynx - LAMP Install (32 bit)",
|
||||||
|
"Ubuntu Linux 10.04 LTS Lucid Lynx - LAMP Install (64 bit)",
|
||||||
|
"Ubuntu Linux 10.04 LTS Lucid Lynx - Minimal Install (32 bit)",
|
||||||
|
"Ubuntu Linux 10.04 LTS Lucid Lynx - Minimal Install (64 bit)",
|
||||||
|
"Ubuntu Linux 8 LTS Hardy Heron - LAMP Install (32 bit)",
|
||||||
|
"Ubuntu Linux 8 LTS Hardy Heron - LAMP Install (64 bit)",
|
||||||
|
"Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (32 bit)",
|
||||||
|
"Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)",
|
||||||
|
"Windows Server 2003 Datacenter SP2 with R2 (32 bit)",
|
||||||
|
"Windows Server 2003 Datacenter SP2 with R2 (64 bit)",
|
||||||
|
"Windows Server 2003 Enterprise SP2 with R2 (64 bit)",
|
||||||
|
"Windows Server 2003 Standard SP2 with R2 (64 bit)",
|
||||||
|
"Windows Server 2008 Datacenter Edition SP2 (32bit)",
|
||||||
|
"Windows Server 2008 Datacenter Edition SP2 (64bit)",
|
||||||
|
"Windows Server 2008 Enterprise Edition SP2 (32bit)",
|
||||||
|
"Windows Server 2008 Enterprise Edition SP2 (64bit)",
|
||||||
|
"Windows Server 2008 R2 Datacenter Edition (64bit)",
|
||||||
|
"Windows Server 2008 R2 Enterprise Edition (64bit)",
|
||||||
|
"Windows Server 2008 R2 Standard Edition (64bit)",
|
||||||
|
"Windows Server 2008 Standard Edition SP2 (32bit)",
|
||||||
|
"Windows Server 2008 Standard Edition SP2 (64bit)");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConversion() {
|
||||||
|
for( String description : operatingSystems )
|
||||||
|
{
|
||||||
|
ProductItem item = ProductItem.builder()
|
||||||
|
.description(description)
|
||||||
|
.price(ProductItemPrice.builder().id(1234).build())
|
||||||
|
.build();
|
||||||
|
Image i = new ProductItemToImage().apply(item);
|
||||||
|
OperatingSystem os = i.getOperatingSystem();
|
||||||
|
assertNotNull(os);
|
||||||
|
assertNotNull(os.getFamily());
|
||||||
|
assertFalse(os.getFamily().equals(OsFamily.UNRECOGNIZED));
|
||||||
|
assertNotNull(os.getVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUbuntu() {
|
||||||
|
ProductItem item = ProductItem.builder()
|
||||||
|
.description("Ubuntu Linux 10.04 LTS Lucid Lynx - Minimal Install (64 bit)")
|
||||||
|
.price(ProductItemPrice.builder().id(1234).build())
|
||||||
|
.build();
|
||||||
|
Image i = new ProductItemToImage().apply(item);
|
||||||
|
OperatingSystem os = i.getOperatingSystem();
|
||||||
|
assertNotNull(os);
|
||||||
|
assertEquals(OsFamily.UBUNTU, os.getFamily());
|
||||||
|
assertEquals("10.04",os.getVersion());
|
||||||
|
assertTrue(os.is64Bit());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testId() {
|
||||||
|
ProductItemPrice price = ProductItemPrice.builder().id(1234).build();
|
||||||
|
ProductItem item = ProductItem.builder().price(price).build();
|
||||||
|
assertEquals("1234",imageId().apply(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIdManyPrices() {
|
||||||
|
ProductItemPrice price1 = ProductItemPrice.builder().id(1234).build();
|
||||||
|
ProductItemPrice price2 = ProductItemPrice.builder().id(5678).build();
|
||||||
|
ProductItem item = ProductItem.builder().prices(ImmutableSet.of(price1,price2)).build();
|
||||||
|
assertEquals("1234",imageId().apply(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = NoSuchElementException.class)
|
||||||
|
public void testIdMissingPrices() {
|
||||||
|
ProductItem item = ProductItem.builder().build();
|
||||||
|
imageId().apply(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOsFamily() {
|
||||||
|
ProductItem item = ProductItem.builder().description("Ubuntu Linux os").build();
|
||||||
|
assertEquals(OsFamily.UBUNTU,osFamily().apply(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOsFamilyUnrecognized() {
|
||||||
|
ProductItem item = ProductItem.builder().description("not a known operating system").build();
|
||||||
|
assertEquals(OsFamily.UNRECOGNIZED,osFamily().apply(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBitsWithSpace() {
|
||||||
|
ProductItem item = ProductItem.builder().description("a (32 bit) os").build();
|
||||||
|
assertEquals(osBits().apply(item),new Integer(32));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBitsNoSpace() {
|
||||||
|
ProductItem item = ProductItem.builder().description("a (64bit) os").build();
|
||||||
|
assertEquals(osBits().apply(item),new Integer(64));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = NoSuchElementException.class)
|
||||||
|
public void testBitsMissing() {
|
||||||
|
ProductItem item = ProductItem.builder().description("an os").build();
|
||||||
|
osBits().apply(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOsVersion() {
|
||||||
|
ProductItem item = ProductItem.builder().description("Windows Server 2099 (256 bit)").build();
|
||||||
|
assertEquals("2099",osVersion().apply(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = NoSuchElementException.class)
|
||||||
|
public void testOsVersionMissing() {
|
||||||
|
ProductItem item = ProductItem.builder().description("asd Server").build();
|
||||||
|
osVersion().apply(item);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.softlayer.compute.functions;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
import org.jclouds.compute.domain.Processor;
|
||||||
|
import org.jclouds.compute.domain.Volume;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItem;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItemCategory;
|
||||||
|
import org.jclouds.softlayer.domain.ProductItemPrice;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jclouds.softlayer.compute.functions.ProductItemsToHardware.hardwareId;
|
||||||
|
import static org.testng.AssertJUnit.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests {@code ProductItemsToHardware}
|
||||||
|
*
|
||||||
|
* @author Jason King
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit")
|
||||||
|
public class ProductItemsToHardwareTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHardwareId() {
|
||||||
|
ProductItem item1 = ProductItem.builder().price(ProductItemPrice.builder().id(123).build()).build();
|
||||||
|
ProductItem item2 = ProductItem.builder().price(ProductItemPrice.builder().id(456).build()).build();
|
||||||
|
ProductItem item3 = ProductItem.builder().price(ProductItemPrice.builder().id(789).build()).build();
|
||||||
|
|
||||||
|
String id = hardwareId().apply(ImmutableList.of(item1, item2, item3));
|
||||||
|
assertEquals("123,456,789",id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHardware() {
|
||||||
|
ProductItem cpuItem = ProductItem.builder()
|
||||||
|
.id(1)
|
||||||
|
.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()
|
||||||
|
.id(3)
|
||||||
|
.description("100 GB (SAN)")
|
||||||
|
.capacity(100F)
|
||||||
|
.price(ProductItemPrice.builder().id(789).build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Hardware hardware = new ProductItemsToHardware().apply(ImmutableSet.of(cpuItem,ramItem,volumeItem));
|
||||||
|
|
||||||
|
assertEquals("123,456,789",hardware.getId());
|
||||||
|
|
||||||
|
List<? extends Processor> processors = hardware.getProcessors();
|
||||||
|
assertEquals(1,processors.size());
|
||||||
|
assertEquals(2.0,processors.get(0).getCores());
|
||||||
|
|
||||||
|
assertEquals(2, hardware.getRam());
|
||||||
|
|
||||||
|
List<? extends Volume> volumes = hardware.getVolumes();
|
||||||
|
assertEquals(1,volumes.size());
|
||||||
|
assertEquals(100F,volumes.get(0).getSize());
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,6 @@ import java.util.Set;
|
||||||
|
|
||||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
||||||
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||||
import static org.jclouds.softlayer.reference.SoftLayerConstants.CLOUD_SERVER_PACKAGE_NAME;
|
|
||||||
import static org.testng.Assert.*;
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +41,14 @@ import static org.testng.Assert.*;
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live")
|
@Test(groups = "live")
|
||||||
public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the package used for ordering virtual guests.
|
||||||
|
* For real this is passed in using the property
|
||||||
|
* @{code org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME}
|
||||||
|
*/
|
||||||
|
public static final String CLOUD_SERVER_PACKAGE_NAME = "Cloud Server";
|
||||||
|
|
||||||
@BeforeGroups(groups = { "live" })
|
@BeforeGroups(groups = { "live" })
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
super.setupClient();
|
super.setupClient();
|
||||||
|
|
|
@ -34,7 +34,6 @@ import java.util.Set;
|
||||||
|
|
||||||
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
|
||||||
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
|
||||||
import static org.jclouds.softlayer.reference.SoftLayerConstants.CLOUD_SERVER_PACKAGE_NAME;
|
|
||||||
import static org.testng.Assert.*;
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,7 +80,7 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pkgId = Iterables.find(context.getApi().getAccountClient().getActivePackages(),named(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(),
|
||||||
|
|
|
@ -38,6 +38,7 @@ public class ProductItemPredicatesTest {
|
||||||
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))
|
.categories(ImmutableSet.of(ramCategory))
|
||||||
.capacity(2.0f)
|
.capacity(2.0f)
|
||||||
.units("GB")
|
.units("GB")
|
||||||
|
@ -88,4 +89,14 @@ public class ProductItemPredicatesTest {
|
||||||
public void testUnitsMissing() {
|
public void testUnitsMissing() {
|
||||||
assertFalse(ProductItemPredicates.units("Kg").apply(item));
|
assertFalse(ProductItemPredicates.units("Kg").apply(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMatchesRegex() {
|
||||||
|
assert ProductItemPredicates.matches(".*test.*").apply(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNoMatchRegex() {
|
||||||
|
assertFalse(ProductItemPredicates.matches("no match").apply(item));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue