From 753bf9f066ef9673ce341f756ab07a083c27e1ec Mon Sep 17 00:00:00 2001 From: Jason King Date: Tue, 27 Sep 2011 13:05:29 +0100 Subject: [PATCH] Issue 158: Functions to convert to Image/Hardware, tests and adject the adapter --- .../SoftLayerComputeServiceContextModule.java | 10 +- .../ProductItemPricesToHardware.java | 48 ------ .../compute/functions/ProductItemToImage.java | 66 ++++++--- .../functions/ProductItemsToHardware.java | 139 ++++++++++++++++++ .../SoftLayerComputeServiceAdapter.java | 28 ++-- .../functions/ProductItemToImageTest.java | 44 +++++- .../functions/ProductItemsToHardwareTest.java | 110 ++++++++++++++ 7 files changed, 353 insertions(+), 92 deletions(-) delete mode 100644 sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemPricesToHardware.java create mode 100644 sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardware.java create mode 100644 sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardwareTest.java diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/config/SoftLayerComputeServiceContextModule.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/config/SoftLayerComputeServiceContextModule.java index fb70c5a4f0..ac512f778b 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/config/SoftLayerComputeServiceContextModule.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/config/SoftLayerComputeServiceContextModule.java @@ -29,7 +29,7 @@ import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; import org.jclouds.softlayer.SoftLayerAsyncClient; import org.jclouds.softlayer.SoftLayerClient; import org.jclouds.softlayer.compute.functions.DatacenterToLocation; -import org.jclouds.softlayer.compute.functions.ProductItemPricesToHardware; +import org.jclouds.softlayer.compute.functions.ProductItemsToHardware; import org.jclouds.softlayer.compute.functions.ProductItemToImage; import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata; import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter; @@ -45,7 +45,7 @@ import java.util.Set; * @author Adrian Cole */ public class SoftLayerComputeServiceContextModule extends - ComputeServiceAdapterContextModule, ProductItemPrice, Datacenter> { + ComputeServiceAdapterContextModule, ProductItem, Datacenter> { public SoftLayerComputeServiceContextModule() { super(SoftLayerClient.class, SoftLayerAsyncClient.class); @@ -54,14 +54,14 @@ public class SoftLayerComputeServiceContextModule extends @Override protected void configure() { super.configure(); - bind(new TypeLiteral, ProductItemPrice, Datacenter>>() {}) + bind(new TypeLiteral, ProductItem, Datacenter>>() {}) .to(SoftLayerComputeServiceAdapter.class); bind(new TypeLiteral>() {}) .to(VirtualGuestToNodeMetadata.class); bind(new TypeLiteral>() {}) .to(ProductItemToImage.class); - bind(new TypeLiteral, org.jclouds.compute.domain.Hardware>>() {}) - .to(ProductItemPricesToHardware.class); + bind(new TypeLiteral, org.jclouds.compute.domain.Hardware>>() {}) + .to(ProductItemsToHardware.class); bind(new TypeLiteral>() {}) .to(DatacenterToLocation.class); bind(new TypeLiteral>() {}) diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemPricesToHardware.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemPricesToHardware.java deleted file mode 100644 index 2b8ba0b0ed..0000000000 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemPricesToHardware.java +++ /dev/null @@ -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, Hardware> { - - @Override - public Hardware apply(Set 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. of(new VolumeImpl(from.disk, true, false))); - return builder.build(); - } - -} diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java index 45e86ebbc0..a26dbf9c8a 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java @@ -18,10 +18,7 @@ */ package org.jclouds.softlayer.compute.functions; -import javax.annotation.Resource; -import javax.inject.Named; -import javax.inject.Singleton; - +import com.google.common.base.Function; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.OperatingSystem; @@ -29,13 +26,17 @@ 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 com.google.common.base.Function; - +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 */ @@ -57,21 +58,21 @@ public class ProductItemToImage implements Function { protected Logger logger = Logger.NULL; @Override - public Image apply(ProductItem from) { + public Image apply(ProductItem productItem) { + checkNotNull(productItem,"productItem"); - //Somehow this method gets called with the correct product item. - OsFamily family = osFamily().apply(from); - Integer bits = osBits().apply(from); + OsFamily family = osFamily().apply(productItem); + Integer bits = osBits().apply(productItem); OperatingSystem os = OperatingSystem.builder() - .description(from.getDescription()) + .description(productItem.getDescription()) .family(family) - .version(osVersion().apply(from)) + .version(osVersion().apply(productItem)) .is64Bit(bits.equals(64)) .build(); return new ImageBuilder() - .id("" + from.getId()) - .description(from.getDescription()) + .id(imageId().apply(productItem)) + .description(productItem.getDescription()) .operatingSystem(os) .build(); } @@ -84,13 +85,15 @@ public class ProductItemToImage implements Function { return new Function() { @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; + 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; } }; @@ -105,6 +108,8 @@ public class ProductItemToImage implements Function { return new Function() { @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); @@ -113,7 +118,7 @@ public class ProductItemToImage implements Function { 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 parseVersion for item:"+productItem); + else throw new NoSuchElementException("No os version for item:"+productItem); } }; } @@ -134,6 +139,8 @@ public class ProductItemToImage implements Function { return new Function() { @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)); @@ -141,7 +148,22 @@ public class ProductItemToImage implements Function { throw new NoSuchElementException("Cannot determine os-bits for item:"+productItem); } } - }; + }; } + /** + * Generates an id for an Image. + * @return the generated id + */ + public static Function imageId() { + return new Function() { + @Override + public String apply(ProductItem productItem) { + checkNotNull(productItem,"productItem"); + ProductItemPrice price = ProductItems.price().apply(productItem); + return ""+price.getId(); + } + }; + } + } diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardware.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardware.java new file mode 100644 index 0000000000..1268474d2f --- /dev/null +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardware.java @@ -0,0 +1,139 @@ +/** + * 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 com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +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.domain.ProductItem; +import org.jclouds.softlayer.domain.ProductItemPrice; + +import javax.inject.Singleton; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.regex.Pattern; + +import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode; +import static org.jclouds.softlayer.predicates.ProductItemPredicates.units; + +/** + * 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, Hardware> { + + private static final double CORE_SPEED = 2.0; + private static final Pattern SAN_REGEX = Pattern.compile(".*GB \\(SAN\\).*"); + + @Override + public Hardware apply(Set from) { + + ProductItem coresItem = getCoresItem(from); + ProductItem ramItem = getRamItem(from); + ProductItem volumeItem = bootVolume().apply(from); + + final String hardwareId = hardwareId().apply(ImmutableList.of(coresItem, ramItem, volumeItem)); + final double cores = getCores(coresItem); + final int ram = getRam(ramItem); + final float volumeSize = ProductItems.capacity().apply(volumeItem); + + return new HardwareBuilder() + .id(hardwareId) + .processors(ImmutableList.of(new Processor(cores, CORE_SPEED))) + .ram(ram) + .volumes(ImmutableList. 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,String> hardwareId() { + return new Function,String>() { + @Override + public String apply(List 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(",")); + } + }; + } + + /** + * Finds an item that is usable as the hardware volume (is a SAN) + * @return The product item + * @throws java.util.NoSuchElementException if the item cannot be found + */ + public static Function,ProductItem> bootVolume() { + return new Function,ProductItem>() { + @Override + public ProductItem apply(Set productItems) { + for(ProductItem item: productItems) { + String description = item.getDescription(); + if (SAN_REGEX.matcher(description).matches()) { + return item; + } + } + throw new NoSuchElementException("cannot find suitable boot volume item"); + } + }; + } + + private ProductItem getCoresItem(Set from) { + Iterable cpuItems = Iterables.filter(from, units("PRIVATE_CORE")); + Map coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity()); + assert coresToProductItem.size() == 1 : "Must have 1 cpu product item:"+coresToProductItem; + + return coresToProductItem.entrySet().iterator().next().getValue(); + } + + private double getCores(ProductItem from) { + return ProductItems.capacity().apply(from).doubleValue(); + } + + private ProductItem getRamItem(Set from) { + Iterable ramItems = Iterables.filter(from,categoryCode("ram")); + Map ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity()); + assert ramToProductItem.size() == 1 : "Must have 1 ram product item:"+ramToProductItem; + + return ramToProductItem.entrySet().iterator().next().getValue(); + } + + private int getRam(ProductItem from) { + return ProductItems.capacity().apply(from).intValue(); + } +} diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/strategy/SoftLayerComputeServiceAdapter.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/strategy/SoftLayerComputeServiceAdapter.java index db1bc6f349..7ab92e1d84 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/strategy/SoftLayerComputeServiceAdapter.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/strategy/SoftLayerComputeServiceAdapter.java @@ -18,29 +18,27 @@ */ package org.jclouds.softlayer.compute.strategy; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; -import java.util.Set; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.domain.Template; import org.jclouds.domain.Credentials; import org.jclouds.softlayer.SoftLayerClient; import org.jclouds.softlayer.domain.Datacenter; -import org.jclouds.softlayer.domain.ProductItemPrice; +import org.jclouds.softlayer.domain.ProductItem; import org.jclouds.softlayer.domain.ProductPackage; import org.jclouds.softlayer.domain.VirtualGuest; import org.jclouds.softlayer.predicates.ProductPackagePredicates; import org.jclouds.softlayer.reference.SoftLayerConstants; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; +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.checkNotNull; /** * defines the connection between the {@link SoftLayerClient} implementation and the jclouds @@ -49,7 +47,7 @@ import com.google.common.collect.Iterables; */ @Singleton public class SoftLayerComputeServiceAdapter implements - ComputeServiceAdapter, ProductItemPrice, Datacenter> { + ComputeServiceAdapter, ProductItem, Datacenter> { private final SoftLayerClient client; private final String virtualGuestPackageName; @@ -76,13 +74,13 @@ public class SoftLayerComputeServiceAdapter implements } @Override - public Iterable> listHardwareProfiles() { + public Iterable> listHardwareProfiles() { // TODO: get the set of product item prices corresponding to the hardware profiles return ImmutableSet.of(); } @Override - public Iterable listImages() { + public Iterable listImages() { // TODO: get the list of product item prices corresponding to images return ImmutableSet.of(); } diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java index 7f2a56afa8..94e7cd5607 100644 --- a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java @@ -1,9 +1,11 @@ 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; @@ -75,7 +77,10 @@ public class ProductItemToImageTest { public void testConversion() { for( String description : operatingSystems ) { - ProductItem item = ProductItem.builder().description(description).build(); + 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); @@ -85,6 +90,41 @@ public class ProductItemToImageTest { } } + @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(); @@ -123,7 +163,7 @@ public class ProductItemToImageTest { @Test(expectedExceptions = NoSuchElementException.class) public void testOsVersionMissing() { - ProductItem item = ProductItem.builder().description("asd Server ").build(); + ProductItem item = ProductItem.builder().description("asd Server").build(); osVersion().apply(item); } } diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardwareTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardwareTest.java new file mode 100644 index 0000000000..8ae04493d7 --- /dev/null +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardwareTest.java @@ -0,0 +1,110 @@ +/** + * 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 java.util.NoSuchElementException; + +import static org.jclouds.softlayer.compute.functions.ProductItemsToHardware.bootVolume; +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 testBootVolume() { + ProductItem item1 = ProductItem.builder().id(1).description("Not a SAN").build(); + ProductItem item2 = ProductItem.builder().id(2).description("100 GB (SAN)").build(); + + ProductItem found = bootVolume().apply(ImmutableSet.of(item1,item2)); + assertEquals(item2,found); + } + + @Test(expectedExceptions = NoSuchElementException.class) + public void testBootVolumeMissing() { + ProductItem item1 = ProductItem.builder().id(1).description("Not a SAN").build(); + bootVolume().apply(ImmutableSet.of(item1)); + } + + @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 processors = hardware.getProcessors(); + assertEquals(1,processors.size()); + assertEquals(2.0,processors.get(0).getCores()); + + assertEquals(2, hardware.getRam()); + + List volumes = hardware.getVolumes(); + assertEquals(1,volumes.size()); + assertEquals(100F,volumes.get(0).getSize()); + } +}