diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/DatacenterToLocation.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/DatacenterToLocation.java index f36d1ba039..556de62e72 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/DatacenterToLocation.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/DatacenterToLocation.java @@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import javax.inject.Inject; +import static com.google.common.base.Strings.nullToEmpty; import org.jclouds.domain.Location; import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; @@ -58,7 +59,16 @@ public class DatacenterToLocation implements Function { } private Iterable createIso3166Codes(Address address) { - return address != null ? ImmutableSet. of("" + address.getCountry() + "-" + address.getState()) - : ImmutableSet. of(); + if (address== null) return ImmutableSet. of(); + + final String country = nullToEmpty(address.getCountry()).trim(); + if (country.isEmpty()) return ImmutableSet. of(); + + final String state = nullToEmpty(address.getState()).trim(); + if (state.isEmpty()) return ImmutableSet. of(address.getCountry()); + + return ImmutableSet. of("" + country + "-" + state); + + } } diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemPriceFromProductItem.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemPriceFromProductItem.java new file mode 100644 index 0000000000..25489eebfb --- /dev/null +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemPriceFromProductItem.java @@ -0,0 +1,46 @@ +/** + * 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.softlayer.domain.ProductItem; +import org.jclouds.softlayer.domain.ProductItemPrice; + +import java.util.NoSuchElementException; +import java.util.Set; + +/** + * Returns the ProductItemPrice for the ProductItem. + * @author Jason King + */ +public class ProductItemPriceFromProductItem implements Function { + + /** + * + * @param productItem the productItem to use + * @return the productItemPrice + * @throws java.util.NoSuchElementException if not only 1 price + */ + @Override + public ProductItemPrice apply(ProductItem productItem) { + Set prices = productItem.getPrices(); + if(prices.size()!=1) throw new NoSuchElementException(); + return prices.iterator().next(); + } +} diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItems.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItems.java new file mode 100644 index 0000000000..7ba9344dfb --- /dev/null +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItems.java @@ -0,0 +1,49 @@ +/** + * 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.softlayer.domain.ProductItem; + +public class ProductItems { + + /** + * Creates a function to get the capacity from a product item. + */ + public static Function capacity() { + return new Function() { + @Override + public Float apply(ProductItem productItem) { + return productItem.getCapacity(); + } + }; + } + + /** + * Creates a function to get the description from a product item. + */ + public static Function description() { + return new Function() { + @Override + public String apply(ProductItem productItem) { + return productItem.getDescription(); + } + }; + } +} diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/Address.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/Address.java index b3d632d62b..c686dea005 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/Address.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/Address.java @@ -18,6 +18,9 @@ */ package org.jclouds.softlayer.domain; +import static com.google.common.base.Strings.emptyToNull; +import static com.google.common.base.Preconditions.checkNotNull; + /** * * @author Jason King @@ -79,7 +82,7 @@ public class Address implements Comparable
{ public Address(long id, String country, String state, String description) { this.id = id; - this.country = country; + this.country = checkNotNull(emptyToNull(country),"country cannot be null or empty:"+country); this.state = state; this.description = description; } diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/ProductItem.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/ProductItem.java index ad1d3a6164..e806e95662 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/ProductItem.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/ProductItem.java @@ -18,14 +18,13 @@ */ package org.jclouds.softlayer.domain; -import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import org.jclouds.javax.annotation.Nullable; import java.util.Set; -import org.jclouds.javax.annotation.Nullable; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; +import static com.google.common.base.Preconditions.checkNotNull; /** * The SoftLayer_Product_Item data type contains general information relating to @@ -50,6 +49,7 @@ public class ProductItem implements Comparable { private String units; private Float capacity; private Set prices = Sets.newLinkedHashSet(); + private Set categories = Sets.newLinkedHashSet(); public Builder id(long id) { this.id = id; @@ -81,13 +81,27 @@ public class ProductItem implements Comparable { return this; } + public Builder category(ProductItemCategory categories) { + this.categories.add(checkNotNull(categories, "categories")); + return this; + } + + public Builder categories(Iterable categories) { + this.categories = ImmutableSet. copyOf(checkNotNull(categories, "categories")); + return this; + } + public ProductItem build() { - return new ProductItem(id, description, units, capacity, prices); + return new ProductItem(id, description, units, capacity, prices, categories); } public static Builder fromProductItem(ProductItem in) { - return ProductItem.builder().id(in.getId()).description(in.getDescription()).units(in.getUnits()) - .capacity(in.getCapacity()).prices(in.getPrices()); + return ProductItem.builder().id(in.getId()) + .description(in.getDescription()) + .units(in.getUnits()) + .capacity(in.getCapacity()) + .prices(in.getPrices()) + .categories(in.getCategories()); } } @@ -96,18 +110,21 @@ public class ProductItem implements Comparable { private String units; private Float capacity; private Set prices = Sets.newLinkedHashSet(); + private Set categories = Sets.newLinkedHashSet(); // for deserializer ProductItem() { } - public ProductItem(long id, String description, String units, Float capacity, Iterable prices) { + public ProductItem(long id, String description, String units, Float capacity, + Iterable prices, Iterable categories) { this.id = id; this.description = description; this.units = units; this.capacity = capacity; this.prices = ImmutableSet. copyOf(checkNotNull(prices, "prices")); + this.categories = ImmutableSet. copyOf(checkNotNull(categories, "categories")); } @Override @@ -155,6 +172,14 @@ public class ProductItem implements Comparable { return prices; } + /** + * + * @return An item's associated item categories. + */ + public Set getCategories() { + return categories; + } + public Builder toBuilder() { return Builder.fromProductItem(this); } @@ -184,6 +209,6 @@ public class ProductItem implements Comparable { @Override public String toString() { return "ProductItem [id=" + id + ", description=" + description + ", units=" + units + ", capacity=" + capacity - + ", prices=" + prices + "]"; + + ", prices=" + prices + ", categories=" + categories + "]"; } } diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/ProductItemCategory.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/ProductItemCategory.java new file mode 100644 index 0000000000..5d3de0551e --- /dev/null +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/domain/ProductItemCategory.java @@ -0,0 +1,140 @@ +/** + * 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.domain; + +/** + * The SoftLayer_Product_Item_Category data type contains + * general category information for prices. + * + * @author Jason King + * @see + */ +public class ProductItemCategory implements Comparable { + + // TODO there are more elements than this. + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private long id = -1; + private String name; + private String categoryCode; + + public Builder id(long id) { + this.id = id; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder categoryCode(String categoryCode) { + this.categoryCode = categoryCode; + return this; + } + + public ProductItemCategory build() { + return new ProductItemCategory(id, name, categoryCode); + } + + public static Builder fromProductItemCategory(ProductItemCategory in) { + return ProductItemCategory.builder().id(in.getId()) + .name(in.getName()) + .categoryCode(in.getCategoryCode()); + } + } + + private long id = -1; + private String name; + private String categoryCode; + + // for deserializer + ProductItemCategory() { + + } + + public ProductItemCategory(long id, String name, String categoryCode) { + this.id = id; + this.name = name; + this.categoryCode = categoryCode; + } + + @Override + public int compareTo(ProductItemCategory arg0) { + return new Long(id).compareTo(arg0.getId()); + } + + /** + * @return The unique identifier of a specific location. + */ + public long getId() { + return id; + } + + /** + * @return The friendly, descriptive name of the category as seen on the order forms and on invoices. + */ + public String getName() { + return name; + } + + /** + * @return The code used to identify this category. + */ + public String getCategoryCode() { + return categoryCode; + } + + public Builder toBuilder() { + return Builder.fromProductItemCategory(this); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (id ^ (id >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ProductItemCategory other = (ProductItemCategory) obj; + if (id != other.id) + return false; + return true; + } + + @Override + public String toString() { + return "ProductItemCategory [id=" + id + ", name=" + name + ", categoryCode=" + categoryCode + "]"; + } +} diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/ProductPackageAsyncClient.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/ProductPackageAsyncClient.java index 6313fdaa01..7a11d7501c 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/ProductPackageAsyncClient.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/features/ProductPackageAsyncClient.java @@ -43,7 +43,7 @@ import javax.ws.rs.core.MediaType; @RequestFilters(BasicAuthentication.class) @Path("/v{jclouds.api-version}") public interface ProductPackageAsyncClient { - public static String PRODUCT_MASK = "items;locations.locationAddress"; + public static String PRODUCT_MASK = "items.prices;items.categories;locations.locationAddress"; /** * @see ProductPackageClient#getProductPackage diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/predicates/ProductItemPredicates.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/predicates/ProductItemPredicates.java new file mode 100644 index 0000000000..d8f540e83c --- /dev/null +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/predicates/ProductItemPredicates.java @@ -0,0 +1,97 @@ +/** + * 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.predicates; + +import com.google.common.base.Predicate; +import org.jclouds.softlayer.domain.ProductItem; +import org.jclouds.softlayer.domain.ProductItemCategory; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class ProductItemPredicates { + + /** + * Tests if the ProductItem contains the required category. + * @param category + * @return true if it does, otherwise false. + */ + public static Predicate categoryCode(final String category) { + checkNotNull(category, "category cannot be null"); + return new Predicate() { + @Override + public boolean apply(ProductItem productItem) { + checkNotNull(productItem, "productItem cannot ne null"); + for(ProductItemCategory productItemCategory: productItem.getCategories()) { + if(category.equals(productItemCategory.getCategoryCode())) return true; + } + return false; + } + + @Override + public String toString() { + return "categoryCode("+category+")"; + } + }; + } + + /** + * Tests if the ProductItem has the required capacity. + * @param capacity + * @return true if it does, otherwise false. + */ + public static Predicate capacity(final Float capacity) { + checkNotNull(capacity, "capacity cannot be null"); + return new Predicate() { + @Override + public boolean apply(ProductItem productItem) { + checkNotNull(productItem, "productItem cannot ne null"); + Float productItemCapacity = productItem.getCapacity(); + if (productItemCapacity == null) return false; + return capacity.equals(productItemCapacity); + } + + @Override + public String toString() { + return "capacity("+capacity+")"; + } + }; + } + + /** + * Tests if the ProductItem has the required units. + * TODO Write test method + * @param units + * @return true if it does, otherwise false. + */ + public static Predicate units(final String units) { + checkNotNull(units, "units cannot be null"); + return new Predicate() { + @Override + public boolean apply(ProductItem productItem) { + checkNotNull(productItem, "productItem cannot ne null"); + return units.equals(productItem.getUnits()); + } + + @Override + public String toString() { + return "units("+units+")"; + } + }; + } +} diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/predicates/ProductPackagePredicates.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/predicates/ProductPackagePredicates.java index 67481f3154..e97a3b2df9 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/predicates/ProductPackagePredicates.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/predicates/ProductPackagePredicates.java @@ -18,9 +18,10 @@ */ package org.jclouds.softlayer.predicates; +import com.google.common.base.Predicate; import org.jclouds.softlayer.domain.ProductPackage; -import com.google.common.base.Predicate; +import static com.google.common.base.Preconditions.checkNotNull; public class ProductPackagePredicates { @@ -32,7 +33,8 @@ public class ProductPackagePredicates { public static Predicate named(final String packageName) { return new Predicate() { public boolean apply(ProductPackage productPackage) { - return productPackage.getName().equals(packageName); + checkNotNull(productPackage, "productPackage cannot be null"); + return productPackage.getName().equals(packageName); } }; } diff --git a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/reference/SoftLayerConstants.java b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/reference/SoftLayerConstants.java index 8640e596a4..ec97fa6a09 100644 --- a/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/reference/SoftLayerConstants.java +++ b/sandbox-providers/softlayer/src/main/java/org/jclouds/softlayer/reference/SoftLayerConstants.java @@ -18,6 +18,11 @@ */ package org.jclouds.softlayer.reference; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; + +import java.util.Set; + /** * Configuration properties and constants used in SoftLayer connections. * @@ -28,5 +33,17 @@ public interface SoftLayerConstants { * Name of the product package corresponding to cloud servers */ public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME = "jclouds.softlayer.virtualguest.package-name"; - + + public static final Set DEFAULT_VIRTUAL_GUEST_PRICES = ImmutableSet.builder() + .add(1639L) // 100 GB (SAN) + .add(21L) // 1 IP Address + .add(55L) // Host Ping + .add(58L) // Automated Notification + .add(1800L) // 0 GB Bandwidth + .add(57L) // Email and Ticket + .add(274L) // 1000 Mbps Public & Private Networks + .add(905L) // Reboot / Remote Console + .add(418L) // Nessus Vulnerability Assessment & Reporting + .add(420L) // Unlimited SSL VPN Users & 1 PPTP VPN User per account + .build(); } diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/DatacenterToLocationTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/DatacenterToLocationTest.java index 9de3ce59ec..520e3aaf2e 100644 --- a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/DatacenterToLocationTest.java +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/DatacenterToLocationTest.java @@ -50,12 +50,19 @@ public class DatacenterToLocationTest { @Test public void testDatacenterToLocation() { - Datacenter address = Datacenter.builder().id(1).longName("This is Texas!").locationAddress( - Address.builder().country("US").state("TX").description("This is Texas!").build()).build(); + Address address = Address.builder().country("US") + .state("TX") + .description("This is Texas!") + .build(); - Location location = function.apply(address); + Datacenter datacenter = Datacenter.builder().id(1) + .longName("Texas Datacenter") + .locationAddress(address) + .build(); - assertEquals(location.getId(), Long.toString(address.getId())); + Location location = function.apply(datacenter); + + assertEquals(location.getId(), Long.toString(datacenter.getId())); Set iso3166Codes = location.getIso3166Codes(); assertEquals(iso3166Codes.size(), 1); assertTrue(iso3166Codes.contains("US-TX")); @@ -63,11 +70,53 @@ public class DatacenterToLocationTest { @Test public void testGetIso3166CodeNoCountryAndState() { - Datacenter address = Datacenter.builder().id(1).longName("Nowhere").build(); - Location location = function.apply(address); + Datacenter datacenter = Datacenter.builder().id(1) + .longName("Nowhere") + .build(); - assertEquals(location.getId(), Long.toString(address.getId())); + Location location = function.apply(datacenter); + + assertEquals(location.getId(), Long.toString(datacenter.getId())); Set iso3166Codes = location.getIso3166Codes(); assertEquals(iso3166Codes.size(), 0); } + + @Test + public void testGetIso3166CodeCountryOnly() { + Address address = Address.builder().country("US") + .description("This is North America!") + .build(); + + Datacenter datacenter = Datacenter.builder().id(1) + .longName("Nowhere") + .locationAddress(address) + .build(); + + Location location = function.apply(datacenter); + + assertEquals(location.getId(), Long.toString(datacenter.getId())); + Set iso3166Codes = location.getIso3166Codes(); + assertEquals(iso3166Codes.size(), 1); + assertTrue(iso3166Codes.contains("US")); + } + + @Test + public void testGetIso3166CodeWhitespaceTrimmer() { + Address address = Address.builder().country(" US ") + .state(" TX ") + .description("This is spaced out Texas") + .build(); + + Datacenter datacenter = Datacenter.builder().id(1) + .longName("Nowhere") + .locationAddress(address) + .build(); + + Location location = function.apply(datacenter); + + assertEquals(location.getId(), Long.toString(datacenter.getId())); + Set iso3166Codes = location.getIso3166Codes(); + assertEquals(iso3166Codes.size(), 1); + assertTrue(iso3166Codes.contains("US-TX")); + } } diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemsTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemsTest.java new file mode 100644 index 0000000000..a1f2cb5906 --- /dev/null +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/compute/functions/ProductItemsTest.java @@ -0,0 +1,64 @@ +/** + * 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 org.jclouds.softlayer.domain.ProductItem; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import static org.jclouds.softlayer.compute.functions.ProductItems.capacity; +import static org.jclouds.softlayer.compute.functions.ProductItems.description; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +/** + * Tests {@code ProductItems} + * + * @author Jason King + */ +@Test(groups = "unit") +public class ProductItemsTest { + + private ProductItem item; + + @BeforeMethod + public void setup() { + item = ProductItem.builder().id(1).capacity(2.0f).description("an item").build(); + } + @Test + public void testCapacity() { + assertEquals(capacity().apply(item), 2.0f); + } + + @Test + public void testCapacityMissing() { + ProductItem item = ProductItem.builder().id(1).build(); + assertNull(capacity().apply(item)); + } + + @Test + public void testDescription() { + assertEquals(description().apply(item),"an item"); + } + + public void testDescriptionMissing() { + ProductItem item = ProductItem.builder().id(1).build(); + assertNull(description().apply(item)); + } +} diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/domain/AddressTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/domain/AddressTest.java new file mode 100644 index 0000000000..d6d91242a2 --- /dev/null +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/domain/AddressTest.java @@ -0,0 +1,40 @@ +/** + * 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.domain; + +import org.testng.annotations.Test; + +/** + * Tests {@code Address} + * + * @author Jason King + */ +@Test(singleThreaded = true, groups = "unit") +public class AddressTest { + + @Test(expectedExceptions = java.lang.NullPointerException.class ) + public void testConstructionWithEmpty() { + Address.builder().country(null).build(); + } + + @Test(expectedExceptions = java.lang.NullPointerException.class ) + public void testConstructionWithNoCountry() { + Address.builder().country("").build(); + } +} diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/ProductPackageAsyncClientTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/ProductPackageAsyncClientTest.java index 377e62ddee..c31dfc9b11 100644 --- a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/ProductPackageAsyncClientTest.java +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/ProductPackageAsyncClientTest.java @@ -43,7 +43,7 @@ public class ProductPackageAsyncClientTest extends BaseSoftLayerAsyncClientTest< assertRequestLineEquals( httpRequest, - "GET https://api.softlayer.com/rest/v3/SoftLayer_Product_Package/1234.json?objectMask=items%3Blocations.locationAddress HTTP/1.1"); + "GET https://api.softlayer.com/rest/v3/SoftLayer_Product_Package/1234.json?objectMask=items.prices%3Bitems.categories%3Blocations.locationAddress HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertPayloadEquals(httpRequest, null, null, false); diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/ProductPackageClientLiveTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/ProductPackageClientLiveTest.java index 4833a1f5d8..a9338e5c17 100644 --- a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/ProductPackageClientLiveTest.java +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/features/ProductPackageClientLiveTest.java @@ -18,16 +18,23 @@ */ package org.jclouds.softlayer.features; +import com.google.common.base.Predicates; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; - +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.jclouds.softlayer.compute.functions.ProductItemPriceFromProductItem; +import org.jclouds.softlayer.compute.functions.ProductItems; import org.jclouds.softlayer.domain.*; -import org.jclouds.softlayer.predicates.ProductPackagePredicates; +import org.jclouds.softlayer.reference.SoftLayerConstants; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; +import java.util.Map; import java.util.Set; +import static org.jclouds.softlayer.predicates.ProductItemPredicates.*; +import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named; import static org.testng.Assert.*; /** @@ -42,6 +49,10 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest { super.setupClient(); client = context.getApi().getProductPackageClient(); accountClient = context.getApi().getAccountClient(); + + // This is used several times, so cache to speed up the test. + cloudServerPackageId = Iterables.find(accountClient.getActivePackages(),named(CLOUD_SERVER_PACKAGE_NAME)).getId(); + cloudServerProductPackage = client.getProductPackage(cloudServerPackageId); } private static final String CLOUD_SERVER_PACKAGE_NAME = "Cloud Server"; @@ -49,6 +60,9 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest { private ProductPackageClient client; private AccountClient accountClient; + private long cloudServerPackageId; + private ProductPackage cloudServerProductPackage; + @Test public void testGetProductPackage() { for (ProductPackage productPackage : accountClient.getActivePackages()) { @@ -85,13 +99,7 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest { Set expected = builder.build(); - // note we don't need to check null, as this will throw NoSuchElementException if - // a product package named as below isn't found. - long productPackageId = Iterables.find(accountClient.getActivePackages(), - ProductPackagePredicates.named(CLOUD_SERVER_PACKAGE_NAME)).getId(); - - ProductPackage productPackage = client.getProductPackage(productPackageId); - Set datacenters = productPackage.getDatacenters(); + Set datacenters = cloudServerProductPackage.getDatacenters(); assertEquals(datacenters.size(), expected.size()); assertTrue(datacenters.containsAll(expected)); @@ -102,9 +110,73 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest { } } + @Test + public void testGetOneGBRamPrice() { + //Predicate p = Predicates.and(ProductItemPredicates.categoryCode("ram"),ProductItemPredicates.capacity(1.0f)); + Iterable ramItems = Iterables.filter(cloudServerProductPackage.getItems(), + Predicates.and(categoryCode("ram"), capacity(1.0f))); + + // capacity is key in GB (1Gb = 1.0f) + Map ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity()); + + ProductItemPrice price = new ProductItemPriceFromProductItem().apply(ramToProductItem.get(1.0f)); + assert new Long(1644L).equals(price.getId()); + } + + @Test + public void testGetTwoCPUCoresPrice() { + // If use ProductItemPredicates.categoryCode("guest_core") get duplicate capacities (units = PRIVATE_CORE and N/A) + Iterable cpuItems = Iterables.filter(cloudServerProductPackage.getItems(), Predicates.and(units("PRIVATE_CORE"), capacity(2.0f))); + + // number of cores is the key + Map coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity()); + + ProductItemPrice price = new ProductItemPriceFromProductItem().apply(coresToProductItem.get(2.0f)); + assert new Long(1963L).equals(price.getId()); + } + + @Test + public void testGetUbuntuPrice() { + Iterable operatingSystems = Iterables.filter(cloudServerProductPackage.getItems(), categoryCode("os")); + + Map osToProductItem = Maps.uniqueIndex(operatingSystems, ProductItems.description()); + + ProductItemPrice price = new ProductItemPriceFromProductItem().apply(osToProductItem.get("Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)")); + assert new Long(1693L).equals(price.getId()); + } + + @Test + public void testPricesForLaunchingGuestVM() { + Iterable ramItems = Iterables.filter(cloudServerProductPackage.getItems(), + Predicates.and(categoryCode("ram"), capacity(1.0f))); + + Map ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity()); + + ProductItemPrice ramPrice = new ProductItemPriceFromProductItem().apply(ramToProductItem.get(1.0f)); + + Iterable cpuItems = Iterables.filter(cloudServerProductPackage.getItems(), Predicates.and(units("PRIVATE_CORE"), capacity(2.0f))); + Map coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity()); + + ProductItemPrice cpuPrice = new ProductItemPriceFromProductItem().apply(coresToProductItem.get(2.0f)); + + Iterable operatingSystems = Iterables.filter(cloudServerProductPackage.getItems(), categoryCode("os")); + Map osToProductItem = Maps.uniqueIndex(operatingSystems, ProductItems.description()); + ProductItemPrice osPrice = new ProductItemPriceFromProductItem().apply(osToProductItem.get("Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)")); + + Set prices = Sets.newLinkedHashSet(); + prices.addAll(SoftLayerConstants.DEFAULT_VIRTUAL_GUEST_PRICES); + prices.add(ramPrice.getId()); + prices.add(cpuPrice.getId()); + prices.add(osPrice.getId()); + + //This should be everything needed to launch Ubuntu Hardy Heron with 1GB Ram and 2 CPU Cores + //TODO: There must be a more concise way of expressing this logic. + } + private void checkProductItem(ProductItem item) { assert item.getId() > 0 : item; assert item.getDescription() != null : item; + checkCategories(item.getCategories()); // units and capacity may be null assertTrue(item.getPrices().size() >= 0); @@ -134,4 +206,12 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest { assert address.getCountry() != null : address; assert address.getState() != null : address; } + + private void checkCategories(Set categories) { + for( ProductItemCategory category: categories ) { + assert category.getId() >0 : category; + assert category.getName() != null : category; + assert category.getCategoryCode() != null : category; + } + } } diff --git a/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/predicates/ProductItemPredicatesTest.java b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/predicates/ProductItemPredicatesTest.java new file mode 100644 index 0000000000..dfee60da70 --- /dev/null +++ b/sandbox-providers/softlayer/src/test/java/org/jclouds/softlayer/predicates/ProductItemPredicatesTest.java @@ -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.predicates; + +import com.google.common.collect.ImmutableSet; +import org.jclouds.softlayer.domain.ProductItem; +import org.jclouds.softlayer.domain.ProductItemCategory; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertFalse; + +@Test(sequential = true,groups = "unit") +public class ProductItemPredicatesTest { + + private ProductItemCategory ramCategory; + private ProductItem item; + private ProductItem emptyItem; + + @BeforeGroups(groups = { "unit" }) + public void setupClient() { + ramCategory = ProductItemCategory.builder().id(1).categoryCode("ram").build(); + + item = ProductItem.builder().id(1) + .categories(ImmutableSet.of(ramCategory)) + .capacity(2.0f) + .units("GB") + .build(); + + emptyItem = ProductItem.builder().id(1).build(); + } + + @Test + public void testCategoryCodePresent() { + assert ProductItemPredicates.categoryCode("ram").apply(item); + } + + @Test + public void testCategoryCodePresentTwoCategories() { + ProductItemCategory osCategory = ProductItemCategory.builder() + .id(2).categoryCode("os") + .build(); + + ProductItem item = ProductItem.builder() + .categories(ImmutableSet.of(ramCategory, osCategory)) + .build(); + + assert ProductItemPredicates.categoryCode("ram").apply(item); + } + + @Test + public void testCategoryCodeMissing() { + assertFalse(ProductItemPredicates.categoryCode("missing").apply(emptyItem)); + } + + @Test + public void testCapacityPresent() { + assert ProductItemPredicates.capacity(2.0f).apply(item); + } + + @Test + public void testCapacityMissing() { + assertFalse(ProductItemPredicates.capacity(1.0f).apply(item)); + } + + @Test + public void testUnitsPresent() { + assert ProductItemPredicates.units("GB").apply(item); + } + + @Test + public void testUnitsMissing() { + assertFalse(ProductItemPredicates.units("Kg").apply(item)); + } +} \ No newline at end of file