JCLOUDS-213: Fixing SoftLayer support

This commit is contained in:
Andrea Turli 2013-07-29 18:43:08 +02:00 committed by Andrew Phillips
parent 0298318790
commit f278450355
21 changed files with 38608 additions and 148 deletions

View File

@ -91,7 +91,7 @@ public class SoftLayerProviderMetadata extends BaseProviderMetadata {
.apiMetadata(new SoftLayerApiMetadata())
.homepage(URI.create("http://www.softlayer.com"))
.console(URI.create("https://manage.softlayer.com"))
.iso3166Codes("SG","US-CA","US-TX","US-VA","US-WA","US-TX", "NL")
.iso3166Codes("SG","US-CA","US-TX","US-VA","US-WA","US-TX", "NL", "NSFTW-IL") // NSFTW-IL is a weird isoCode returned by Softlayer
.endpoint("https://api.softlayer.com/rest")
.defaultProperties(SoftLayerProviderMetadata.defaultProperties());
}

View File

@ -101,7 +101,7 @@ public class SoftLayerComputeServiceContextModule extends
public ProductPackage get() {
AccountClient accountClient = client.getAccountClient();
ProductPackageClient productPackageClient = client.getProductPackageClient();
ProductPackage p = find(accountClient.getActivePackages(), named(virtualGuestPackageName));
ProductPackage p = find(accountClient.getReducedActivePackages(), named(virtualGuestPackageName));
return productPackageClient.getProductPackage(p.getId());
}

View File

@ -16,15 +16,8 @@
*/
package org.jclouds.softlayer.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
@ -34,8 +27,13 @@ import org.jclouds.logging.Logger;
import org.jclouds.softlayer.domain.ProductItem;
import org.jclouds.softlayer.domain.ProductItemPrice;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* @author Jason King
@ -162,7 +160,6 @@ public class ProductItemToImage implements Function<ProductItem, Image> {
return Integer.parseInt(m.group(1));
}
}
return null;
}
};
@ -179,7 +176,7 @@ public class ProductItemToImage implements Function<ProductItem, Image> {
public String apply(ProductItem productItem) {
checkNotNull(productItem, "productItem");
ProductItemPrice price = ProductItems.price().apply(productItem);
return "" + price.getId();
return String.valueOf(checkNotNull(price, "price").getId());
}
};
}

View File

@ -19,6 +19,9 @@ package org.jclouds.softlayer.compute.functions;
import java.util.NoSuchElementException;
import java.util.Set;
import com.google.common.collect.Sets;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.softlayer.domain.ProductItem;
import org.jclouds.softlayer.domain.ProductItemCategory;
import org.jclouds.softlayer.domain.ProductItemPrice;
@ -26,6 +29,9 @@ import org.jclouds.softlayer.domain.ProductItemPrice;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import javax.annotation.Resource;
import javax.inject.Named;
public class ProductItems {
/**
@ -60,7 +66,7 @@ public class ProductItems {
return new Function<ProductItem, ProductItemPrice>() {
@Override
public ProductItemPrice apply(ProductItem productItem) {
if (productItem.getPrices().size() < 1)
if (productItem.getPrices().isEmpty())
throw new NoSuchElementException("ProductItem has no prices:" + productItem);
return Iterables.get(productItem.getPrices(), 0);
}

View File

@ -88,10 +88,8 @@ public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMe
if (image != null) {
builder.imageId(image.getId());
builder.operatingSystem(image.getOperatingSystem());
builder.hardware(hardware.getHardware(from));
}
builder.hardware(hardware.getHardware(from));
builder.status(serverStateToNodeStatus.get(from.getPowerState().getKeyName()));
// These are null for 'bad' guest orders in the HALTED state.
@ -147,6 +145,8 @@ public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMe
return null;
Iterable<ProductItem> items = Iterables.transform(order.getPrices(), ProductItems.item());
ProductItem os = Iterables.find(items, ProductItemPredicates.categoryCode("os"));
if (os.getPrices().isEmpty())
return null;
return new ProductItemToImage().apply(os);
}
}

View File

@ -65,7 +65,6 @@ import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
/**
* defines the connection between the {@link SoftLayerClient} implementation and

View File

@ -140,7 +140,7 @@ public class ProductOrder {
private final boolean useHourlyPricing;
@ConstructorProperties({
"packageId", "location", "prices", "virtualGuest", "quantity", "useHourlyPricing"
"packageId", "location", "prices", "virtualGuests", "quantity", "useHourlyPricing"
})
protected ProductOrder(int packageId, @Nullable String location, @Nullable Set<ProductItemPrice> prices, @Nullable Set<VirtualGuest> virtualGuests, int quantity, boolean useHourlyPricing) {
this.packageId = packageId;

View File

@ -26,6 +26,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.QueryParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.softlayer.domain.ProductPackage;
@ -34,7 +35,7 @@ import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Account via their REST API.
* <p/>
*
*
* @see AccountClient
* @see <a href="http://sldn.softlayer.com/article/REST" />
* @author Jason King
@ -46,6 +47,16 @@ import com.google.common.util.concurrent.ListenableFuture;
public interface AccountAsyncClient {
/**
* @see AccountClient#getReducedActivePackages()
*/
@GET
@Path("/SoftLayer_Account/ActivePackages.json")
@Consumes(MediaType.APPLICATION_JSON)
@Fallback(NullOnNotFoundOr404.class)
@QueryParams(keys = "objectMask", values = "id;name")
ListenableFuture<Set<ProductPackage>> getReducedActivePackages();
/**
* @see AccountClient#getActivePackages()
*/
@GET
@ -54,5 +65,4 @@ public interface AccountAsyncClient {
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Set<ProductPackage>> getActivePackages();
}

View File

@ -31,15 +31,15 @@ import org.jclouds.softlayer.domain.ProductPackage;
public interface AccountClient {
/**
*
* @return Gets all the active packages.
* This will give you a basic description of the packages that are currently
* active and from which you can order a server or additional services.
*
* Calling ProductPackage.getItems() will return an empty set.
* Use ProductPackageClient.getProductPackage(long id) to obtain items data.
* @see ProductPackageClient#getProductPackage
* @return return all the active packages.
*/
Set<ProductPackage> getActivePackages();
/**
* @return return all the active packages's id and name.
* @see #getActivePackages()
*/
Set<ProductPackage> getReducedActivePackages();
}

View File

@ -21,9 +21,12 @@ import static org.testng.Assert.assertFalse;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;
import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials;
@ -67,7 +70,7 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
@Test
public void testListLocations() {
assertFalse(Iterables.isEmpty(adapter.listLocations()));
assertFalse(Iterables.isEmpty(adapter.listLocations()), "locations must not be empty");
}
private static final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate = new PrioritizeCredentialsFromTemplate(
@ -128,4 +131,11 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
protected Iterable<Module> setupModules() {
return ImmutableSet.<Module> of(getLoggingModule(), new SshjSshClientModule());
}
@Override
protected Properties setupProperties() {
Properties properties = super.setupProperties();
properties.setProperty("jclouds.ssh.max-retries", "10");
return properties;
}
}

View File

@ -24,13 +24,15 @@ import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
import java.util.Properties;
/**
*
*
* Generally disabled, as it incurs higher fees.
*
*
* @author Adrian Cole
*/
@Test(groups = "live", enabled = true, sequential = true)
@Test(groups = "live", enabled = true, singleThreaded = true)
public class SoftLayerComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public SoftLayerComputeServiceLiveTest() {
@ -42,7 +44,7 @@ public class SoftLayerComputeServiceLiveTest extends BaseComputeServiceLiveTest
protected Module getSshModule() {
return new SshjSshClientModule();
}
// softlayer does not support metadata
@Override
protected void checkUserMetadataContains(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
@ -54,4 +56,11 @@ public class SoftLayerComputeServiceLiveTest extends BaseComputeServiceLiveTest
public void testOptionToNotBlock() {
// start call is blocking anyway.
}
}
@Override
protected Properties setupProperties() {
Properties properties = super.setupProperties();
properties.setProperty("jclouds.ssh.max-retries", "20");
return properties;
}
}

View File

@ -47,6 +47,8 @@ import com.google.common.collect.ImmutableSet;
@Test(groups = "live")
public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
public static final int MAX_RAM = 48 * 1024;
public SoftLayerTemplateBuilderLiveTest() {
provider = "softlayer";
}
@ -141,7 +143,7 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes
Template template = context.getComputeService().templateBuilder().biggest().build();
assertEquals(getCores(template.getHardware()), 16.0d);
assertEquals(template.getHardware().getRam(), 16*1024);
assertEquals(template.getHardware().getRam(), MAX_RAM);
assertEquals(getSpace(template.getHardware()), 100.0d);
assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.SAN);
} finally {
@ -181,7 +183,7 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes
Template template = context.getComputeService().templateBuilder().biggest().build();
assertEquals(getCores(template.getHardware()), 8.0d);
assertEquals(template.getHardware().getRam(), 16*1024);
assertEquals(template.getHardware().getRam(), MAX_RAM);
assertEquals(getSpace(template.getHardware()), 100.0d);
assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.LOCAL);
} finally {
@ -203,14 +205,14 @@ public class SoftLayerTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes
public void testBiggestTemplateBuilder() throws IOException {
Template template = view.getComputeService().templateBuilder().biggest().build();
assertEquals(getCores(template.getHardware()), 16.0d);
assertEquals(template.getHardware().getRam(), 16*1024);
assertEquals(template.getHardware().getRam(), MAX_RAM);
assertEquals(getSpace(template.getHardware()), 100.0d);
assertEquals(template.getHardware().getVolumes().get(0).getType(), Volume.Type.LOCAL);
}
@Override
protected Set<String> getIso3166Codes() {
return ImmutableSet.<String> of("SG", "US-CA", "US-TX", "US-VA", "US-WA", "NL");
return ImmutableSet.<String> of("SG", "US-CA", "US-TX", "US-VA", "US-WA", "NL", "NSFTW-IL");
}
}

View File

@ -20,11 +20,11 @@ import static org.jclouds.softlayer.compute.functions.ProductItemToImage.imageId
import static org.jclouds.softlayer.compute.functions.ProductItemToImage.osBits;
import static org.jclouds.softlayer.compute.functions.ProductItemToImage.osFamily;
import static org.jclouds.softlayer.compute.functions.ProductItemToImage.osVersion;
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 static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.util.Arrays;
import java.util.List;
@ -125,8 +125,8 @@ public class ProductItemToImageTest {
Image i = new ProductItemToImage().apply(item);
OperatingSystem os = i.getOperatingSystem();
assertNotNull(os);
assertEquals(OsFamily.UBUNTU, os.getFamily());
assertEquals("10.04",os.getVersion());
assertEquals(os.getFamily(), OsFamily.UBUNTU);
assertEquals(os.getVersion(), "10.04");
assertTrue(os.is64Bit());
}
@ -139,8 +139,8 @@ public class ProductItemToImageTest {
Image i = new ProductItemToImage().apply(item);
OperatingSystem os = i.getOperatingSystem();
assertNotNull(os);
assertEquals(OsFamily.UBUNTU, os.getFamily());
assertEquals("10.04",os.getVersion());
assertEquals(os.getFamily(), OsFamily.UBUNTU);
assertEquals(os.getVersion(), "10.04");
assertFalse(os.is64Bit());
}
@ -154,7 +154,7 @@ public class ProductItemToImageTest {
Image i = new ProductItemToImage().apply(item);
OperatingSystem os = i.getOperatingSystem();
assertNotNull(os);
assertEquals(OsFamily.UNRECOGNIZED, os.getFamily());
assertEquals(os.getFamily(), OsFamily.UNRECOGNIZED);
assertNull(os.getVersion());
assertFalse(os.is64Bit());
}
@ -168,7 +168,7 @@ public class ProductItemToImageTest {
Image i = new ProductItemToImage().apply(item);
OperatingSystem os = i.getOperatingSystem();
assertNotNull(os);
assertEquals(OsFamily.UNRECOGNIZED, os.getFamily());
assertEquals(os.getFamily(), OsFamily.UNRECOGNIZED);
assertNull(os.getVersion());
assertTrue(os.is64Bit());
}
@ -189,16 +189,16 @@ public class ProductItemToImageTest {
@Test
public void testId() {
ProductItemPrice price = ProductItemPrice.builder().id(1234).build();
ProductItem item = ProductItem.builder().prices(price).build();
assertEquals("1234",imageId().apply(item));
ProductItem item = ProductItem.builder().id(5678).prices(price).build();
assertEquals(imageId().apply(item), "1234", "Expected the ID of the ProductItemPrice to be returned");
}
@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));
ProductItem item = ProductItem.builder().id(9012).prices(ImmutableSet.of(price1,price2)).build();
assertEquals(imageId().apply(item), "1234", "Expected the ID of the ProductItemPrice to be returned");
}
@Test(expectedExceptions = NoSuchElementException.class)
@ -214,17 +214,17 @@ public class ProductItemToImageTest {
@Test
public void testOsFamily() {
assertEquals(OsFamily.UBUNTU,osFamily().apply("Ubuntu Linux os"));
assertEquals(osFamily().apply("Ubuntu Linux os"), OsFamily.UBUNTU);
}
@Test
public void testOsFamilyUnrecognized() {
assertEquals(OsFamily.UNRECOGNIZED,osFamily().apply("not a known operating system"));
assertEquals(osFamily().apply("not a known operating system"), OsFamily.UNRECOGNIZED);
}
@Test
public void testOsFamilyNull() {
assertEquals(OsFamily.UNRECOGNIZED,osFamily().apply(null));
assertEquals(osFamily().apply(null), OsFamily.UNRECOGNIZED);
}
@Test
@ -249,7 +249,7 @@ public class ProductItemToImageTest {
@Test
public void testOsVersion() {
assertEquals("2099",osVersion().apply("Windows Server 2099 (256 bit)"));
assertEquals(osVersion().apply("Windows Server 2099 (256 bit)"), "2099");
}
@Test

View File

@ -0,0 +1,130 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.features;
import com.google.common.collect.ImmutableSet;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.internal.BaseRestClientExpectTest;
import org.jclouds.softlayer.SoftLayerClient;
import org.jclouds.softlayer.domain.ProductPackage;
import org.testng.annotations.Test;
import java.net.URI;
import static org.testng.Assert.assertEquals;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "AccountClientExpectTest")
public class AccountClientExpectTest extends BaseRestClientExpectTest<SoftLayerClient> {
public static String ACTIVE_PACKAGE_MASK = "id;name";
public AccountClientExpectTest() {
provider = "softlayer";
}
public void testGetActivePackagesWhenResponseIs2xx() {
SoftLayerClient client = requestSendsResponse(HttpRequest.builder().method("GET")
.endpoint("https://api.softlayer.com/rest/v3/SoftLayer_Account/ActivePackages.json")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==")
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/get_active_packages.json"))
.build());
assertEquals(client.getAccountClient().getActivePackages(),
ImmutableSet.of(
ProductPackage.builder()
.id(13)
.name("Dual Xeon (Dual Core) Woodcrest/Cloverton")
.description("<div class=\"PageTopicSubHead\">Dual Processor Multi-core Servers</div>")
.build(),
ProductPackage.builder()
.id(15)
.name("Single Xeon (Dual Core) Woodcrest/Cloverton")
.description("<div class=\"PageTopicSubHead\">Single Processor Multi-core Servers</div>")
.build()));
}
public void testGetActivePackagesWhenResponseIs404() {
SoftLayerClient client = requestSendsResponse(HttpRequest.builder()
.method("GET")
.endpoint("https://api.softlayer.com/rest/v3/SoftLayer_Account/ActivePackages.json")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==")
.build(),
HttpResponse.builder()
.statusCode(404)
.build());
assertEquals(client.getAccountClient().getActivePackages(), null);
}
public void testGetReducedActivePackagesWhenResponseIs2xx() {
SoftLayerClient client = requestSendsResponse(
HttpRequest.builder().method("GET")
.endpoint("https://api.softlayer.com/rest/v3/SoftLayer_Account/ActivePackages.json")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==")
.addQueryParam("objectMask", ACTIVE_PACKAGE_MASK)
.build(),
HttpResponse.builder()
.statusCode(200)
.payload(payloadFromResource("/get_reduced_active_packages.json"))
.build());
assertEquals(client.getAccountClient().getReducedActivePackages(),
ImmutableSet.of(
ProductPackage.builder()
.id(13)
.name("Dual Xeon (Dual Core) Woodcrest/Cloverton")
.description("<div class=\"PageTopicSubHead\">Dual Processor Multi-core Servers</div>")
.build(),
ProductPackage.builder()
.id(15)
.name("Single Xeon (Dual Core) Woodcrest/Cloverton")
.description("<div class=\"PageTopicSubHead\">Single Processor Multi-core Servers</div>")
.build()));
}
public void testGetReducedActivePackagesWhenResponseIs404() {
SoftLayerClient client = requestSendsResponse(
HttpRequest.builder()
.method("GET")
.endpoint("https://api.softlayer.com/rest/v3/SoftLayer_Account/ActivePackages.json")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==")
.addQueryParam("objectMask", ACTIVE_PACKAGE_MASK)
.build(),
HttpResponse.builder()
.statusCode(404)
.build());
assertEquals(client.getAccountClient().getReducedActivePackages(), null);
}
}

View File

@ -20,6 +20,7 @@ import static org.testng.Assert.assertTrue;
import java.util.Set;
import org.jclouds.softlayer.domain.ProductItem;
import org.jclouds.softlayer.domain.ProductPackage;
import org.testng.annotations.Test;
@ -37,11 +38,14 @@ public class AccountClientLiveTest extends BaseSoftLayerClientLiveTest {
assert null != response;
assertTrue(response.size() >= 0);
for (ProductPackage productPackage: response) {
for (ProductPackage p : response) {
ProductPackage productPackage = api.getProductPackageClient().getProductPackage(p.getId());
assert productPackage.getId() > 0 : response;
assert productPackage.getName() != null : response;
assert productPackage.getDescription() != null : response;
assertTrue(productPackage.getItems().isEmpty());
for (ProductItem item : productPackage.getItems()) {
checkProductItem(item);
}
}
}
}

View File

@ -17,9 +17,17 @@
package org.jclouds.softlayer.features;
import org.jclouds.apis.BaseApiLiveTest;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.softlayer.SoftLayerClient;
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.Set;
import static org.testng.Assert.*;
/**
* Tests behavior of {@code SoftLayerClient}
*
@ -31,4 +39,31 @@ public class BaseSoftLayerClientLiveTest extends BaseApiLiveTest<SoftLayerClient
public BaseSoftLayerClientLiveTest() {
this.provider = "softlayer";
}
public void checkProductItem(ProductItem item) {
assertTrue(item.getId() > 0, "item id must be more than 0");
assertNotNull(item.getDescription(), "item description must be not null");
checkCategories(item.getCategories());
// units and capacity may be null
assertFalse(item.getPrices().isEmpty());
for (ProductItemPrice price : item.getPrices()) {
checkPrice(price);
}
}
public void checkCategories(Set<ProductItemCategory> categories) {
for (ProductItemCategory category : categories) {
assertTrue(category.getId() > 0, "category id must be more than 0");
assertNotNull(category.getName(), "category name must be not null");
assertNotNull(category.getCategoryCode(), "category code must be not null");
}
}
public void checkPrice(ProductItemPrice price) {
assertTrue(price.getId() > 0, "price id must be more than 0");
assertTrue(price.getItemId() > 0, "price itemId must be more than 0");
assertTrue(price.getRecurringFee() != null || price.getHourlyRecurringFee() != null,
"price.getRecurringFee() must be not null OR price.getHourlyRecurringFee() must be not null");
}
}

View File

@ -54,19 +54,16 @@ public class DatacenterClientLiveTest extends BaseSoftLayerClientLiveTest {
Builder<Datacenter> builder = ImmutableSet.builder();
builder.add(Datacenter.builder().id(265592).name("ams01").longName("Amsterdam 1").build());
builder.add(Datacenter.builder().id(3).name("dal01").longName("Dallas").build());
builder.add(Datacenter.builder().id(154770).name("dal02").longName("Dallas 2").build());
builder.add(Datacenter.builder().id(167092).name("dal04").longName("Dallas 4").build());
builder.add(Datacenter.builder().id(138124).name("dal05").longName("Dallas 5").build());
builder.add(Datacenter.builder().id(154820).name("dal06").longName("Dallas 6").build());
builder.add(Datacenter.builder().id(142776).name("dal07").longName("Dallas 7").build());
builder.add(Datacenter.builder().id(142775).name("hou02").longName("Houston 2").build());
builder.add(Datacenter.builder().id(18171).name("sea01").longName("Seattle").build());
builder.add(Datacenter.builder().id(168642).name("sjc01").longName("San Jose 1").build());
builder.add(Datacenter.builder().id(2).name("dal00").longName("Corporate HQ").build());
builder.add(Datacenter.builder().id(37473).name("wdc01").longName("Washington, DC").build());
builder.add(Datacenter.builder().id(154770).name("dal02").longName("Dallas 2").build());
builder.add(Datacenter.builder().id(138124).name("dal05").longName("Dallas 5").build());
builder.add(Datacenter.builder().id(167093).name("hou01").longName("Houston 1").build());
builder.add(Datacenter.builder().id(167094).name("lon01").longName("London 1").build());
builder.add(Datacenter.builder().id(167092).name("dal04").longName("Dallas 4").build());
builder.add(Datacenter.builder().id(224092).name("sng01").longName("Singapore 1").build());
builder.add(Datacenter.builder().id(142775).name("hou02").longName("Houston 2").build());
builder.add(Datacenter.builder().id(142776).name("dal07").longName("Dallas 7").build());
builder.add(Datacenter.builder().id(154820).name("dal06").longName("Dallas 6").build());
builder.add(Datacenter.builder().id(37473).name("wdc01").longName("Washington, DC").build());
Set<Datacenter> response = api().listDatacenters();
Set<Datacenter> expected = builder.build();

View File

@ -79,22 +79,18 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
@Test
public void testGetProductPackage() {
for (ProductPackage productPackage : accountClient.getActivePackages()) {
for (ProductPackage productPackage : accountClient.getReducedActivePackages()) {
ProductPackage response = client.getProductPackage(productPackage.getId());
assert null != response;
assert response.getId() > 0 : response;
assert response.getName() != null : response;
assert response.getDescription() != null : response;
assertTrue(response.getItems().size() >= 0);
for (ProductItem item : response.getItems()) {
// ProductItem newDetails = client.getProductItem(item.getId());
// assertEquals(item.getId(), newDetails.getId());
checkProductItem(item);
}
assertTrue(response.getDatacenters().size() > 0);
for (Datacenter datacenter : response.getDatacenters()) {
checkDatacenter(datacenter);
}
@ -127,8 +123,6 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
@Test
public void testGetOneGBRamPrice() {
// Predicate p =
// Predicates.and(ProductItemPredicates.categoryCode("ram"),ProductItemPredicates.capacity(1.0f));
Iterable<ProductItem> ramItems = Iterables.filter(cloudServerProductPackage.getItems(),
Predicates.and(categoryCode("ram"), capacity(1.0f)));
@ -166,28 +160,6 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
assert Integer.valueOf(1693).equals(price.getId());
}
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);
for (ProductItemPrice price : item.getPrices()) {
// ProductItemPrice newDetails =
// client.getProductItemPrice(prices.getId());
// assertEquals(item.getId(), newDetails.getId());
checkPrice(price);
}
}
private void checkPrice(ProductItemPrice price) {
assert price.getId() > 0 : price;
assert price.getItemId() > 0 : price;
assert price.getRecurringFee() != null || price.getHourlyRecurringFee() != null : price;
}
private void checkDatacenter(Datacenter datacenter) {
assert datacenter.getId() > 0 : datacenter;
assert datacenter.getName() != null : datacenter;
@ -207,12 +179,4 @@ public class ProductPackageClientLiveTest extends BaseSoftLayerClientLiveTest {
if (!ImmutableSet.of("SG", "NL").contains(address.getCountry()))
assert address.getState() != null : address;
}
private void checkCategories(Set<ProductItemCategory> categories) {
for (ProductItemCategory category : categories) {
assert category.getId() > 0 : category;
assert category.getName() != null : category;
assert category.getCategoryCode() != null : category;
}
}
}

View File

@ -16,6 +16,9 @@
*/
package org.jclouds.softlayer.features;
import static com.google.common.base.Predicates.and;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.get;
import static org.jclouds.softlayer.predicates.ProductItemPredicates.capacity;
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
@ -29,6 +32,9 @@ import java.util.Properties;
import java.util.Random;
import java.util.Set;
import com.google.common.base.Splitter;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.softlayer.SoftLayerClient;
import org.jclouds.softlayer.compute.functions.ProductItems;
import org.jclouds.softlayer.domain.ProductItem;
@ -51,13 +57,14 @@ import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code VirtualGuestClient}
*
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
private static final String TEST_HOSTNAME_PREFIX = "livetest";
private TemplateBuilder templateBuilder;
@Test
public void testListVirtualGuests() throws Exception {
@ -71,11 +78,8 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
}
}
@Test(enabled = false, groups = "live")
@Test(groups = "live")
public void testCancelAndPlaceOrder() {
// This method was not working needs testing out.
// TODO: Should also check if there are active transactions before trying to cancel.
// objectMask: virtualGuests.activeTransaction
for (VirtualGuest guest : api().listVirtualGuests()) {
@ -90,43 +94,22 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
named(ProductPackageClientLiveTest.CLOUD_SERVER_PACKAGE_NAME)).getId();
ProductPackage productPackage = api.getProductPackageClient().getProductPackage(pkgId);
Iterable<ProductItem> ramItems = Iterables.filter(productPackage.getItems(), Predicates.and(categoryCode("ram"),
capacity(2.0f)));
Map<Float, ProductItem> ramToProductItem = Maps.uniqueIndex(ramItems, ProductItems.capacity());
ProductItemPrice ramPrice = ProductItems.price().apply(ramToProductItem.get(2.0f));
Iterable<ProductItem> cpuItems = Iterables.filter(productPackage.getItems(), Predicates.and(
units("PRIVATE_CORE"), capacity(2.0f)));
Map<Float, ProductItem> coresToProductItem = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
ProductItemPrice cpuPrice = ProductItems.price().apply(coresToProductItem.get(2.0f));
Iterable<ProductItem> operatingSystems = Iterables.filter(productPackage.getItems(), categoryCode("os"));
Map<String, ProductItem> osToProductItem = Maps.uniqueIndex(operatingSystems, ProductItems.description());
ProductItemPrice osPrice = ProductItems.price().apply(
osToProductItem.get("Ubuntu Linux 8 LTS Hardy Heron - Minimal Install (64 bit)"));
Builder<ProductItemPrice> prices = ImmutableSet.builder();
prices.addAll(defaultPrices);
prices.add(ramPrice);
prices.add(cpuPrice);
prices.add(osPrice);
VirtualGuest guest = VirtualGuest.builder().domain("jclouds.org").hostname(
TEST_HOSTNAME_PREFIX + new Random().nextInt()).build();
ProductOrder order = ProductOrder.builder().packageId(pkgId).quantity(1).useHourlyPricing(true).prices(
prices.build()).virtualGuests(guest).build();
Template template = templateBuilder.build();
ProductOrder order = ProductOrder.builder()
.packageId(productPackage.getId())
.quantity(1)
.location(template.getLocation().getId())
.useHourlyPricing(true)
.prices(getPrices(template, productPackage))
.virtualGuests(guest).build();
ProductOrderReceipt receipt = api().orderVirtualGuest(order);
ProductOrder order2 = receipt.getOrderDetails();
VirtualGuest result = Iterables.get(order2.getVirtualGuests(), 0);
ProductOrder order3 = api().getOrderTemplate(result.getId());
assertEquals(order.getPrices(), order3.getPrices());
assertEquals(order.getPrices(), order2.getPrices());
assertNotNull(receipt);
}
@ -135,6 +118,7 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
@Override
protected SoftLayerClient create(Properties props, Iterable<Module> modules) {
Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
templateBuilder = injector.getInstance(TemplateBuilder.class);
defaultPrices = injector.getInstance(Key.get(new TypeLiteral<Iterable<ProductItemPrice>>() {
}));
return injector.getInstance(SoftLayerClient.class);
@ -157,8 +141,6 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
assert vg.getMaxCpu() > 0 : vg;
assert vg.getMaxCpuUnits() != null : vg;
assert vg.getMaxMemory() > 0 : vg;
assert vg.getMetricPollDate() != null : vg;
assert vg.getModifyDate() != null : vg;
assert vg.getStartCpus() > 0 : vg;
assert vg.getStatusId() >= 0 : vg;
assert vg.getUuid() != null : vg;
@ -166,4 +148,22 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
assert vg.getPrimaryIpAddress() != null : vg;
}
private Iterable<ProductItemPrice> getPrices(Template template, ProductPackage productPackage) {
Builder<ProductItemPrice> result = ImmutableSet.builder();
int imageId = Integer.parseInt(template.getImage().getId());
result.add(ProductItemPrice.builder().id(imageId).build());
Iterable<String> hardwareIds = Splitter.on(",").split(template.getHardware().getId());
for (String hardwareId : hardwareIds) {
int id = Integer.parseInt(hardwareId);
result.add(ProductItemPrice.builder().id(id).build());
}
float portSpeed = 10f;
ProductItem uplinkItem = find(productPackage.getItems(),
and(capacity(portSpeed), categoryCode("port_speed")));
result.add(get(uplinkItem.getPrices(), 0));
result.addAll(defaultPrices);
return result.build();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,10 @@
[
{
"id": 13,
"name": "Dual Xeon (Dual Core) Woodcrest/Cloverton"
},
{
"id": 15,
"name": "Single Xeon (Dual Core) Woodcrest/Cloverton"
}
]