diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java index 20d863b876..928ec9eaab 100644 --- a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java +++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java @@ -20,7 +20,6 @@ package org.jclouds.softlayer.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; -import java.util.NoSuchElementException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -38,6 +37,7 @@ import org.jclouds.softlayer.domain.ProductItem; import org.jclouds.softlayer.domain.ProductItemPrice; import com.google.common.base.Function; +import com.google.common.base.Objects; /** * @author Jason King @@ -45,14 +45,16 @@ import com.google.common.base.Function; @Singleton public class ProductItemToImage implements Function { - /** Pattern to capture the number of bits e.g. "a (32 bit) os" */ + /** + * 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 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"; private static final String CLOUD_LINUX = "CloudLinux"; @@ -62,111 +64,123 @@ public class ProductItemToImage implements Function { @Override public Image apply(ProductItem productItem) { - checkNotNull(productItem,"productItem"); + checkNotNull(productItem, "productItem"); + String description = checkNotNull(productItem.getDescription(), "productItem.description"); - OsFamily family = osFamily().apply(productItem); - Integer bits = osBits().apply(productItem); + OsFamily osFamily = osFamily().apply(description); + if (osFamily == OsFamily.UNRECOGNIZED) { + logger.debug("Cannot determine os family for item: %s", productItem); + } + Integer bits = osBits().apply(description); + if (bits == null) { + logger.debug("Cannot determine os bits for item: %s", productItem); + } + String osVersion = osVersion().apply(description); + if (osVersion == null) { + logger.debug("Cannot determine os version for item: %s", productItem); + } OperatingSystem os = OperatingSystem.builder() - .description(productItem.getDescription()) - .family(family) - .version(osVersion().apply(productItem)) - .is64Bit(bits.equals(64)) - .build(); + .description(description) + .family(osFamily) + .version(osVersion) + .is64Bit(Objects.equal(bits, 64)) + .build(); return new ImageBuilder() .ids(imageId().apply(productItem)) - .description(productItem.getDescription()) + .description(description) .operatingSystem(os) .build(); } /** * Parses the item description to determine the OSFamily + * * @return the @see OsFamily or OsFamily.UNRECOGNIZED */ - public static Function osFamily() { - 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; - else if(description.startsWith(CLOUD_LINUX)) return OsFamily.CLOUD_LINUX; - return OsFamily.UNRECOGNIZED; + public static Function osFamily() { + return new Function() { + @Override + public OsFamily apply(final String description) { + if (description != null) { + 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; + else if (description.startsWith(CLOUD_LINUX)) return OsFamily.CLOUD_LINUX; } - }; - } + + 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 + * + * @return the version or null if the version cannot be determined */ - public static Function osVersion() { - return new Function() { - @Override - public String apply(ProductItem productItem) { - checkNotNull(productItem,"productItem"); + public static Function osVersion() { + return new Function() { + @Override + public String apply(final String description) { + OsFamily family = osFamily().apply(description); - 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 if(family.equals(OsFamily.CLOUD_LINUX)) return parseVersion(description, CLOUD_LINUX); - else throw new NoSuchElementException("No os version for item:"+productItem); - } - }; - } + if (Objects.equal(family, OsFamily.CENTOS)) return parseVersion(description, CENTOS); + else if (Objects.equal(family, OsFamily.DEBIAN)) return parseVersion(description, DEBIAN); + else if (Objects.equal(family, OsFamily.FEDORA)) return parseVersion(description, FEDORA); + else if (Objects.equal(family, OsFamily.RHEL)) return parseVersion(description, RHEL); + else if (Objects.equal(family, OsFamily.UBUNTU)) return parseVersion(description, UBUNTU); + else if (Objects.equal(family, OsFamily.WINDOWS)) return parseVersion(description, WINDOWS); + else if (Objects.equal(family, OsFamily.CLOUD_LINUX)) return parseVersion(description, CLOUD_LINUX); - private static String parseVersion(String description, String os) { - String noOsName = description.replaceFirst(os,"").trim(); - return noOsName.split(" ")[0]; - } + return null; + } + }; + } + + 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 + * + * @return the number of bits or null if the number of bits cannot be determined */ - public static Function osBits() { - return new Function() { - @Override - public Integer apply(ProductItem productItem) { - checkNotNull(productItem,"productItem"); - - Matcher m = OS_BITS_PATTERN.matcher(productItem.getDescription()); + public static Function osBits() { + return new Function() { + @Override + public Integer apply(String description) { + if (description != null) { + Matcher m = OS_BITS_PATTERN.matcher(description); 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 imageId() { - return new Function() { + return null; + } + }; + } + + /** + * 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"); + checkNotNull(productItem, "productItem"); ProductItemPrice price = ProductItems.price().apply(productItem); - return ""+price.getId(); + return "" + price.getId(); } }; } diff --git a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java index 94bd1f4550..39f8c9babc 100644 --- a/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java +++ b/providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemToImageTest.java @@ -25,6 +25,7 @@ import static org.jclouds.softlayer.compute.functions.ProductItemToImage.osVersi import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertTrue; import java.util.Arrays; @@ -131,6 +132,62 @@ public class ProductItemToImageTest { assertTrue(os.is64Bit()); } + @Test + public void testUbuntuNoBitCount() { + ProductItem item = ProductItem.builder() + .description("Ubuntu Linux 10.04 LTS Lucid Lynx - Minimal Install") + .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()); + assertFalse(os.is64Bit()); + } + + + @Test + public void testCompletelyUnknown() { + ProductItem item = ProductItem.builder() + .description("This fails to match anything!!!") + .price(ProductItemPrice.builder().id(1234).build()) + .build(); + Image i = new ProductItemToImage().apply(item); + OperatingSystem os = i.getOperatingSystem(); + assertNotNull(os); + assertEquals(OsFamily.UNRECOGNIZED, os.getFamily()); + assertNull(os.getVersion()); + assertFalse(os.is64Bit()); + } + + @Test + public void test64BitUnknown() { + ProductItem item = ProductItem.builder() + .description("This only has the bit-count (64 bit)") + .price(ProductItemPrice.builder().id(1234).build()) + .build(); + Image i = new ProductItemToImage().apply(item); + OperatingSystem os = i.getOperatingSystem(); + assertNotNull(os); + assertEquals(OsFamily.UNRECOGNIZED, os.getFamily()); + assertNull(os.getVersion()); + assertTrue(os.is64Bit()); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testNull() { + new ProductItemToImage().apply(null); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testNoDescription() { + ProductItem item = ProductItem.builder() + .price(ProductItemPrice.builder().id(1234).build()) + .build(); + new ProductItemToImage().apply(item); + } + @Test public void testId() { ProductItemPrice price = ProductItemPrice.builder().id(1234).build(); @@ -151,46 +208,59 @@ public class ProductItemToImageTest { ProductItem item = ProductItem.builder().build(); imageId().apply(item); } + + @Test(expectedExceptions = NullPointerException.class) + public void testIdNull() { + imageId().apply(null); + } @Test public void testOsFamily() { - ProductItem item = ProductItem.builder().description("Ubuntu Linux os").build(); - assertEquals(OsFamily.UBUNTU,osFamily().apply(item)); + assertEquals(OsFamily.UBUNTU,osFamily().apply("Ubuntu Linux os")); } @Test public void testOsFamilyUnrecognized() { - ProductItem item = ProductItem.builder().description("not a known operating system").build(); - assertEquals(OsFamily.UNRECOGNIZED,osFamily().apply(item)); + assertEquals(OsFamily.UNRECOGNIZED,osFamily().apply("not a known operating system")); + } + + @Test + public void testOsFamilyNull() { + assertEquals(OsFamily.UNRECOGNIZED,osFamily().apply(null)); } @Test - public void testBitsWithSpace() { - ProductItem item = ProductItem.builder().description("a (32 bit) os").build(); - assertEquals(osBits().apply(item),new Integer(32)); + public void testOsBitsWithSpace() { + assertEquals(osBits().apply("a (32 bit) os"),new Integer(32)); } @Test - public void testBitsNoSpace() { - ProductItem item = ProductItem.builder().description("a (64bit) os").build(); - assertEquals(osBits().apply(item),new Integer(64)); + public void testOsBitsNoSpace() { + assertEquals(osBits().apply("a (64bit) os"),new Integer(64)); } - @Test(expectedExceptions = NoSuchElementException.class) - public void testBitsMissing() { - ProductItem item = ProductItem.builder().description("an os").build(); - osBits().apply(item); + @Test + public void testOsBitsMissing() { + assertNull(osBits().apply("an os")); + } + + @Test + public void testOsBitsNull() { + assertNull(osBits().apply(null)); } @Test public void testOsVersion() { - ProductItem item = ProductItem.builder().description("Windows Server 2099 (256 bit)").build(); - assertEquals("2099",osVersion().apply(item)); + assertEquals("2099",osVersion().apply("Windows Server 2099 (256 bit)")); } - @Test(expectedExceptions = NoSuchElementException.class) + @Test public void testOsVersionMissing() { - ProductItem item = ProductItem.builder().description("asd Server").build(); - osVersion().apply(item); + assertNull(osVersion().apply("asd Server")); + } + + @Test + public void testOsVersionNull() { + assertNull(osVersion().apply(null)); } }