OrderConsistentPerfBlockStorage.java
OrderConsistentPerfBlockStorage.java
package api.storage;
import com.softlayer.api.ApiClient;
import com.softlayer.api.RestApiClient;
import com.softlayer.api.service.Location;
import com.softlayer.api.service.container.product.order.network.performancestorage.Iscsi;
import com.softlayer.api.service.location.Group;
import com.softlayer.api.service.location.group.Pricing;
import com.softlayer.api.service.network.storage.iscsi.os.Type;
import com.softlayer.api.service.product.Item;
import com.softlayer.api.service.product.Order;
import com.softlayer.api.service.product.Package;
import com.softlayer.api.service.product.item.Price;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* Order a consistent block storage (performance ISCSI).
*
* This example shows how to order a SoftLayer_Container_Product_Order_Network_PerformanceStorage_Iscsi
* by sending following data:
* quantity - Quantity of "Block Storages" to order
* location - Location where storage will be hosted
* storageSize - The size in GB of the Block Storage
* iops - Number of IOPS between "100" and "6000" by intervals of 100.
* osKeyName - The Operating System type used in the ISCSI
*
* Important manual pages:
* http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order
* http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/verifyOrder
* http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/placeOrder
* http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package
* http://sldn.softlayer.com/reference/services/SoftLayer_Product_Package/getItems
* http://sldn.softlayer.com/reference/services/SoftLayer_Location_Group_Pricing
* http://sldn.softlayer.com/reference/services/SoftLayer_Location_Group_Pricing/getAllObjects
* http://sldn.softlayer.com/reference/services/SoftLayer_Location
* http://sldn.softlayer.com/reference/services/SoftLayer_Location/getDatacenters
* http://sldn.softlayer.com/reference/datatypes/SoftLayer_Location_Group_Pricing
* http://sldn.softlayer.com/reference/datatypes/SoftLayer_Location
* http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Network_PerformanceStorage_Nfs
* http://sldn.softlayer.com/reference/datatypes/SoftLayer_Product_Item_Price
* http://sldn.softlayer.com/blog/cmporter/Location-based-Pricing-and-You
* http://sldn.softlayer.com/blog/bpotter/Going-Further-SoftLayer-API-Python-Client-Part-3
* http://sldn.softlayer.com/article/Object-Masks
*
* @license <http://sldn.softlayer.com/article/License>
* @author SoftLayer Technologies, Inc. <sldn@softlayer.com>
* @version 1.0
*
* Required Java version: JDK 8 or higher.
*/
public class OrderConsistentPerfBlockStorage {
private static final String USER_NAME = "set-me";
private static final String API_KEY = "set-me";
// The quantity
public Long quantity = new Long(1);
// Values "ams01", "ams03", "che01", "dal05", "dal06" "fra02", "hkg02", "lon02", etc.
public String location = "dal06";
// Values "20", "40", "80", "100", "200", "250", "500" etc.
public BigDecimal storageSize = new BigDecimal(250);
// Values between "100" and "6000" by intervals of 100.
public BigDecimal iops = new BigDecimal(100);
// Values "LINUX", "HYPER_V", "VMWARE", "WINDOWS", "WINDOWS_2008", "WINDOWS_GPT", "XEN"
public String osKeyName = "LINUX";
// The package id to order a network storage is 222
private static final Long packageId = new Long(222);
// Storage types - required to find item prices
private static final String STORAGE_ISCSI = "performance_storage_iscsi";
private static final String STORAGE_SPACE = "performance_storage_space";
private static final String STORAGE_IOPS = "performance_storage_iops";
public OrderConsistentPerfBlockStorage(){
// Create and instantiate the Api Client object
ApiClient client = new RestApiClient().withCredentials(USER_NAME, API_KEY);
// Call to following SoftLayer Services
Order.Service productOrderService = Order.service(client);
Package.Service packageService = Package.service(client, packageId);
Pricing.Service locationGroupPricingService = Pricing.service(client);
Location.Service locationGroupService = Location.service(client);
// Now we can delete the Scale Group
try {
// Getting the datacenter of location
locationGroupService.withMask().regions();
Location datacenter = locationGroupService.getDatacenters().stream()
.filter( x -> location.equals(x.getName()))
.findFirst()
.get();
// Getting Performance Storage NFS item.
System.out.println("Getting Performance Storage ISCSI item price");
packageService.withMask().items().prices();
List<Item> itemsStorageNfs = packageService.getObject().getItems().stream()
.filter( x -> x.getItemCategory().getCategoryCode().equals(STORAGE_ISCSI))
.collect(Collectors.toList());
// Getting the SoftLayer_Location_Group_Pricing which contains the configured
// location.
locationGroupPricingService.withMask().locations();
Group locationGroup = locationGroupPricingService.getAllObjects().stream()
.filter( gp -> gp.getLocations().stream()
.anyMatch( x -> x.getName().equals(location)))
.findFirst()
.orElse(null);
Long locationId = (locationGroup != null) ? locationGroup.getId() : null;
/*
* Getting the storage space prices which match the configured storage space,
* and are valid for the configured location. In case we did not get a
* location group for the configured location, we are going to search for
* standard prices.
*/
// Use object-mask to get items, categories and avoid a lot of unnecessary data
packageService.withMask().itemPrices().id();
packageService.withMask().itemPrices().locationGroupId();
packageService.withMask().itemPrices().capacityRestrictionMaximum();
packageService.withMask().itemPrices().capacityRestrictionMinimum();
packageService.withMask().itemPrices().item().id();
packageService.withMask().itemPrices().item().capacity();
packageService.withMask().itemPrices().categories().id();
packageService.withMask().itemPrices().categories().categoryCode();
// Get all item prices
System.out.println("Getting available prices in specified package");
List<Price> itemPrices = packageService.getObject().getItemPrices();
// As Java don't support object-filter feature, the following is an useful
// alternative to get performance_storage_space objects
System.out.println("Getting prices of Performance Storage Space objects");
List<Price> pricesStorageSpace = filterStoragePrices(itemPrices,
STORAGE_SPACE,
locationId);
if (pricesStorageSpace.isEmpty()){
System.out.println("Error: The storage space value " + storageSize +
" GB is not valid or it doesn't exists in specified location");
}else{
System.out.println("\tStorage Space price: " +
pricesStorageSpace.get(0).getId());
}
// Following is to get performance_storage_iops objects prices
System.out.println("Getting prices of Performance Storage IOPS objects");
List<Price> pricesStorageIops = filterStoragePrices(itemPrices,
STORAGE_IOPS,
locationId);
if (pricesStorageIops.isEmpty()){
System.out.println("Error: The IOPS value " + iops +
" is not valid for storage space " + storageSize + " GB and "+
"location '" + location + "'.");
}else{
System.out.println("\tStorage IOPS price: " +
pricesStorageIops.get(0).getId());
}
// Build the osFormatType
Type osType = new Type();
osType.setKeyName(osKeyName);
// Set prices that will be used
System.out.println("Building the order of network storage");
List<Price> orderPrices = new ArrayList<Price>(){{
add(itemsStorageNfs.get(0).getPrices().get(0));
add(pricesStorageSpace.get(0));
add(pricesStorageIops.get(0));
}};
// Build the order template
Iscsi orderData = new Iscsi();
orderData.setPackageId(packageId);
orderData.setLocation(datacenter.getRegions().get(0).getKeyname());
orderData.setQuantity(quantity);
orderData.getPrices().addAll(orderPrices);
orderData.setOsFormatType(osType);
/*
* verifyOrder() will check your order for errors. Replace this with a call to
* placeOrder() when you're ready to order. Both calls return a receipt object
* that you can use for your records.
*/
System.out.println("Verifying the order....");
com.softlayer.api.service.container.product.Order order;
order = productOrderService.verifyOrder(orderData);
System.out.println("Verified!! \n\t" + order.toString());
} catch (Exception e) {
System.out.println("Error : " + e.toString());
}
}
// Following function filter the item prices in order to get all available according
// to entered arguments
private List<Price> filterStoragePrices(List<Price> itemPrices,
String storageType,
Long locationId){
List<Price> prices = itemPrices.stream()
.filter(storagePredicate(storageType, locationId))
.collect(Collectors.toList());
if (prices.isEmpty()){
prices = itemPrices.stream()
.filter(storagePredicate(storageType, null))
.collect(Collectors.toList());
}
return prices;
}
// Following function returns the Predicate that will be used during filter
private Predicate<Price> storagePredicate(String storageType, Long locationId){
Predicate<Price> predicate = null;
switch (storageType){
case STORAGE_SPACE:
if (locationId == null){
predicate = price -> price.getItem().getCapacity().equals(storageSize)
&& price.getLocationGroupId() == null
&& price.getCategories().stream()
.anyMatch( category -> category.getCategoryCode()
.equals(storageType));
}else{
predicate = price -> price.getItem().getCapacity().equals(storageSize)
&& price.getLocationGroupId() != null
&& price.getLocationGroupId().equals(locationId)
&& price.getCategories().stream()
.anyMatch( category -> category.getCategoryCode()
.equals(storageType));
}
break;
case STORAGE_IOPS:
if (locationId == null){
predicate = price -> price.getItem().getCapacity().equals(iops)
&& price.getLocationGroupId() == null
&& price.getCategories().stream()
.anyMatch( category -> category.getCategoryCode()
.equals(storageType))
&& Integer.parseInt(price.getCapacityRestrictionMinimum())
<= storageSize.intValue()
&& Integer.parseInt(price.getCapacityRestrictionMaximum())
>= storageSize.intValue();
}else{
predicate = price -> price.getItem().getCapacity().equals(iops)
&& price.getLocationGroupId() != null
&& price.getLocationGroupId().equals(locationId)
&& price.getCategories().stream()
.anyMatch( category -> category.getCategoryCode()
.equals(storageType))
&& Integer.parseInt(price.getCapacityRestrictionMinimum())
<= storageSize.intValue()
&& Integer.parseInt(price.getCapacityRestrictionMaximum())
>= storageSize.intValue();
}
break;
}
return predicate;
}
public static void main(String args[]){
new OrderConsistentPerfBlockStorage();
}
}