0
votes

I want to order an hourly Bare Metal, using Softlayer java API. I took the idea from https://gist.github.com/bmpotter/fe2de7f8028d73ada4e5. Here are my steps:

    Hardware hardware = new Hardware();
    Order orderTemplate = new Order();

    // 1. Set hostname, domain to hardware
    // 2. set Preset 
    Preset preset = new Preset();
    preset.setKeyName("S1270_8GB_2X1TBSATA_NORAID");
    hardware.setFixedConfigurationPreset(preset);
    // 3. Component setMaxSpeed, and added to hardware
    hardware.setPrimaryNetworkComponent()
    // 4. "UBUNTU_14_64"
    hardware.setOperatingSystemReferenceCode()

    // 1. Added Quantity to orderTemplate
    // 2. Added location to orderTemplate
    // 3. Added Hardware to orderTemplate
    // 4. Added Container, since I am see the exception
    orderTemplate.setContainerIdentifier("SoftLayer_Product_Package_Preset");

    Finally tried to verify the Order.

I keep getting a generic error message:

Invalid container specified: SoftLayer_Container_Product_Order. Ordering a server or service requires a specific container type, not the generic base order container.

What am I doing wrong? Do I need to send priceIds, similar to non hourly Bare Metal Order? Is there a troubleshooting guide to know what is missing in my order?

Pedro David Fuentes Can you please help? I tried this, after figuring out the prices:

https://[username]:[apikey]@api.softlayer.com/rest/v3/SoftLayer_Product_Order/verifyOrder

{
   "parameters": [
   {
     "complexType": "SoftLayer_Container_Product_Order_Hardware_Server",
     "quantity": 1,
     "location": "DALLAS",
     "packageId": 200,
     "useHourlyPricing": 1,
     "presetId": 66,
     "prices": [
     {
        "id": 37318
     }, 
     {
        "id": 34183
     }, 
     {
        "id": 26737
     }, 
     {
        "id": 34807
     }, 
     {
        "id": 25014
     }
  ],
  "hardware": [
    {
      "hostname": "myhostname",
      "domain": "mydomain.com"
    }
   ]
  }
 ]
}
{ 
    "error": "Unable to add a Graphics Processing Unit price (178119) because it is not valid for the package (200).", 
    "code": "SoftLayer_Exception_Public" 
}

Also reproducible via JAVA code, hence tried via REST too.

Modified code with extra logging:

String username = "xxxxx";
String apiKey = "xxxxx";

Location datacenter = new Location();
datacenter.setName("seo01");

Preset preset = new Preset();
preset.setKeyName("S1270_8GB_2X1TBSATA_NORAID");

Component networkComponent = new Component();
networkComponent.setMaxSpeed(100L);

Hardware hardware = new Hardware();
hardware.setDatacenter(datacenter);
hardware.setHostname("xxxxx_xxxxx_BM_HOURLY");
hardware.setDomain("xxxx.xxx");
hardware.setHourlyBillingFlag(true);
hardware.setFixedConfigurationPreset(preset);
List<Component> networkComponents = hardware.getNetworkComponents();
networkComponents.add(networkComponent);
hardware.setOperatingSystemReferenceCode("CENTOS_LATEST");

ApiClient client = new RestApiClient().withCredentials(username, apiKey).withLoggingEnabled();
Hardware.Service hardwareService = Hardware.service(client); 
try
{  
  Gson gson = new Gson();
  Hardware hardwarePlaced = hardwareService.createObject(hardware);
  System.out.println("createObject: " + gson.toJson(hardwarePlaced));
}
catch(Exception e)
{
    System.out.println("Error: " + e);  
}

I get an error: Running POST on link with body: {"parameters":[{"complexType":"SoftLayer_Hardware","hostname":"xxxxx_xxxxx_BM_HOURLY","domain":"xxxx.xxx","fixedConfigurationPreset":{"complexType":"SoftLayer_Product_Package_Preset","keyName":"S1270_8GB_2X1TBSATA_NORAID"},"datacenter":{"complexType":"SoftLayer_Location","name":"seo01"},"hourlyBillingFlag":true,"networkComponents":[{"complexType":"SoftLayer_Network_Component","maxSpeed":100}],"operatingSystemReferenceCode":"CENTOS_LATEST"}]} Got 500 on link with body: {"error":"Unable to add a Graphics Processing Unit price (178119) because it is not valid for the package (200).","code":"SoftLayer_Exception_Public"} Error: com.softlayer.api.ApiException$Internal: Unable to add a Graphics Processing Unit price (178119) because it is not valid for the package (200).(code: SoftLayer_Exception_Public, status: 500)

2

2 Answers

0
votes

you could try this script.

package SoftLayer_Java_Scripts.Examples;
import java.util.ArrayList;
import java.util.List;
import com.softlayer.api.*;
import com.softlayer.api.service.container.product.order.hardware.Server;
import com.softlayer.api.service.Hardware;
import com.softlayer.api.service.product.Order;
import com.softlayer.api.service.product.item.Price;
import com.google.gson.Gson;

/**
* Order a new server with preset configuration.
* 
 * The presets used to simplify ordering by eliminating the need
* for price ids when submitting orders.
* Also when the order contains a preset id, it is not possible
* to configure VLANs in the order.
* 
 * Important manual pages:
* http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/verifyOrder
* http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Network_Message_Queue
* http://sldn.softlayer.com/reference/datatypes/SoftLayer_Virtual_Guest
* 
 * @license <http://sldn.softlayer.com/article/License>
* @author SoftLayer Technologies, Inc. <[email protected]>
* @version 1.0
*/
public class OrderPreSetBMS
{
  public static void main( String[] args )
  {
    // Your SoftLayer API username and key.
       String user = "set me";
       String apiKey = "set me";

       long quantity = 1;
       String location = "AMSTERDAM";
       long packageId = 200;
       long presetId = 64;
       String hostname = "test";
       String domain = "example.org";

       // Building a skeleton SoftLayer_Hardware_Server object to model the hostname and
       // domain we want for our server. If you set quantity greater then 1 then you
       // need to define one hostname/domain pair per server you wish to order.
       Hardware hardware = new Hardware();
       hardware.setHostname(hostname);
       hardware.setDomain(domain);

    // Building a skeleton SoftLayer_Product_Item_Price objects. These objects contain
    // much more than ids, but SoftLayer's ordering system only needs the price's id
    // to know what you want to order.
    // Every item in SoftLayer's product catalog is assigned an id. Use these ids
    // to tell the SoftLayer API which options you want in your new server. Use
    // the getActivePackages() method in the SoftLayer_Account API service to get
       // a list of available item and price options per available package.
       // Note: The presets already have some preconfigured items, such as
       // the server or the disks you do not need to configure the prices for those
       // items.
       //
       // Id: 44988 -> CentOS 7.x (64 bit)
    // Id: 1800  -> 0 GB Bandwidth
    // Id: 273   -> 100 Mbps Public & Private Network Uplinks
    // Id: 420   -> Unlimited SSL VPN Users & 1 PPTP VPN User per account
    // Id: 21    -> 1 IP Address
    // Id: 906   -> Reboot / KVM over IP        
    long[] priceIds = {44988, 1800, 273, 420, 21, 906};
    List<Price> prices = new ArrayList<Price>();
    for (int i = 0; i < priceIds.length; i++) {
      Price p = new Price();
      p.setId(priceIds[i]);
      prices.add(p);
    }

    // Building a skeleton SoftLayer_Container_Product_Order_Hardware_Server object
    // containing the order you wish to place.
       Server server = new Server();
       server.setQuantity(quantity);
       server.setLocation(location);
       server.setPackageId(packageId);

    List<Price> priceList = server.getPrices();
    priceList.addAll(prices);

       List<Hardware> hardwareList = server.getHardware();
       hardwareList.add(hardware);
       server.setPresetId(presetId);

       // Creating a SoftLayer API client and service objects. 
       ApiClient client = new RestApiClient().withCredentials(user, apiKey);
       Order.Service service = Order.service(client);

       try
       {
      // 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.
       // Once your order is placed it'll go through SoftLayer's approval and
       // provisioning process. When it's done you'll have a new
       // SoftLayer_Hardware_Server object and server ready to use.
       com.softlayer.api.service.container.product.Order verifiedOrder = service.verifyOrder(server);
         Gson gson = new Gson();
         System.out.println(gson.toJson(verifiedOrder));
       }
       catch(Exception e)
       {
              System.out.println("Error: " + e); 
       }
  }
}

The next REST request retrieves the Product Item Prices for a package Id. Is important to notice how these prices are organized and what information they contain. For example, these product item prices might have the same item id, this is because the prices are separated by location.

 https://$username:[email protected]/rest/v3/SoftLayer_Product_Package/200/getItemPrices.json?objectMask=mask[id,pricingLocationGroup[locations[name]],item[id,description],categories[categoryCode]]

The next Request uses an object filter and Host Ping and TCP Service Monitoring as the search criteria. With this example, one can realize that Product Item Prices can have the same Item Id meaning that they are the same, but should be used according to the specific location where the order is being verified.

 https://$username:[email protected]/rest/v3/SoftLayer_Product_Package/200/getItemPrices.json?objectMask=mask[id,pricingLocationGroup[locations[name]],item[id,description],categories[categoryCode]]&objectFilter={"itemPrices":{"item":{"description":{"operation":"Host Ping and TCP Service Monitoring"}}}} 

For further reading:

https://sldn.softlayer.com/article/object-masks

https://sldn.softlayer.com/article/object-filters

0
votes

This documentation about order BM servers can help you http://sldn.softlayer.com/blog/bpotter/ordering-bare-metal-servers-using-softlayer-api

Here an exmaple to order presets:

import java.util.List;
import com.softlayer.api.*;
import com.softlayer.api.service.Hardware;
import com.softlayer.api.service.Location;
import com.softlayer.api.service.network.Component;
import com.softlayer.api.service.product.Order;
import com.softlayer.api.service.product.pkg.Preset;
import com.google.gson.Gson;

public class OrderPreSetBMS2
{
  public static void main( String[] args )
  {
    String user = "set me";
    String apiKey = "set me";

    Location datacenter = new Location();
    datacenter.setName("seo01");

    Preset preset = new Preset();
    preset.setKeyName("S1270_8GB_2X1TBSATA_NORAID");

    Component networkComponent = new Component();
    networkComponent.setMaxSpeed(100L);


    Hardware hardware = new Hardware();
    hardware.setDatacenter(datacenter);
    hardware.setHostname("simplebmi");
    hardware.setDomain("test.com");
    hardware.setHourlyBillingFlag(true);
    hardware.setFixedConfigurationPreset(preset);
    List<Component> networkComponents = hardware.getNetworkComponents();
    networkComponents.add(networkComponent);
    hardware.setOperatingSystemReferenceCode("UBUNTU_14_64");

    ApiClient client = new RestApiClient().withCredentials(user, apiKey);
    Hardware.Service hardwareService = Hardware.service(client); 
    Order.Service orderService = Order.service(client); 

    try
    {
      //Change generateOrderTemplate method by createObject when you are ready to order the server. 
      com.softlayer.api.service.container.product.Order productOrder = hardwareService.generateOrderTemplate(hardware);
      Gson gson = new Gson();
      System.out.println(gson.toJson(productOrder));
    }
    catch(Exception e)
    {
        System.out.println("Error: " + e);  
    }
  }
}