You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2014/07/16 11:20:51 UTC

[9/9] git commit: [JCLOUDS-474] refactor SoftLayer support

[JCLOUDS-474] refactor SoftLayer support


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/717a545b
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/717a545b
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/717a545b

Branch: refs/heads/master
Commit: 717a545baa5bbc9ae9c78a29a313898abf2403a7
Parents: 09cf571
Author: Andrea Turli <an...@gmail.com>
Authored: Fri Feb 14 11:53:17 2014 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Wed Jul 16 11:05:48 2014 +0200

----------------------------------------------------------------------
 providers/softlayer/pom.xml                     |   15 +-
 .../org/jclouds/softlayer/SoftLayerApi.java     |   29 +-
 .../jclouds/softlayer/SoftLayerApiMetadata.java |   27 +-
 .../softlayer/SoftLayerProviderMetadata.java    |   46 +-
 .../softlayer/binders/ProductOrderToJson.java   |  131 --
 .../jclouds/softlayer/binders/TagToJson.java    |   60 +
 .../softlayer/binders/VirtualGuestToJson.java   |  201 +++
 .../SoftLayerComputeServiceContextModule.java   |   87 +-
 .../compute/functions/DatacenterToLocation.java |   10 +-
 .../functions/OperatingSystemToImage.java       |   92 ++
 .../compute/functions/ProductItemToImage.java   |  184 ---
 .../compute/functions/ProductItems.java         |   90 --
 .../functions/ProductItemsToHardware.java       |  122 --
 .../functions/VirtualGuestToHardware.java       |   65 +
 .../compute/functions/VirtualGuestToImage.java  |   68 +
 .../functions/VirtualGuestToNodeMetadata.java   |  118 +-
 .../functions/internal/OperatingSystems.java    |   91 ++
 .../options/SoftLayerTemplateOptions.java       |   87 +-
 .../SoftLayerComputeServiceAdapter.java         |  484 +++++--
 .../config/SoftLayerHttpApiModule.java          |    4 +-
 .../softlayer/config/SoftLayerParserModule.java |    4 +-
 .../org/jclouds/softlayer/domain/Address.java   |  190 ++-
 .../ContainerVirtualGuestConfiguration.java     |  270 ++++
 ...ontainerVirtualGuestConfigurationOption.java |  109 ++
 .../jclouds/softlayer/domain/Datacenter.java    |   37 +-
 .../softlayer/domain/OperatingSystem.java       |  116 +-
 .../org/jclouds/softlayer/domain/Password.java  |   15 +-
 .../jclouds/softlayer/domain/PowerState.java    |    2 +-
 .../jclouds/softlayer/domain/ProductItem.java   |  250 ++--
 .../softlayer/domain/ProductItemCategory.java   |  153 --
 .../softlayer/domain/ProductItemPrice.java      |  248 ++--
 .../jclouds/softlayer/domain/ProductOrder.java  |  223 ---
 .../softlayer/domain/ProductOrderReceipt.java   |  135 --
 .../softlayer/domain/ProductPackage.java        |  207 ---
 .../org/jclouds/softlayer/domain/Region.java    |    9 +-
 .../softlayer/domain/SoftwareDescription.java   |  301 ++++
 .../softlayer/domain/SoftwareLicense.java       |  130 ++
 .../java/org/jclouds/softlayer/domain/Tag.java  |  140 ++
 .../jclouds/softlayer/domain/TagReference.java  |  218 +++
 .../org/jclouds/softlayer/domain/TagType.java   |  104 ++
 .../softlayer/domain/VirtualDiskImage.java      |  249 ++++
 .../domain/VirtualDiskImageSoftware.java        |  126 ++
 .../jclouds/softlayer/domain/VirtualGuest.java  |  225 ++-
 .../domain/VirtualGuestBlockDevice.java         |  241 ++++
 .../domain/VirtualGuestBlockDeviceTemplate.java |  202 +++
 .../VirtualGuestBlockDeviceTemplateGroup.java   |  256 ++++
 .../domain/VirtualGuestNetworkComponent.java    |  248 ++++
 .../SoftLayerOrderItemDuplicateException.java   |   29 -
 .../jclouds/softlayer/features/AccountApi.java  |   45 +-
 .../softlayer/features/DatacenterApi.java       |   13 +-
 .../softlayer/features/ProductPackageApi.java   |   56 -
 .../features/SoftwareDescriptionApi.java        |   52 +
 .../softlayer/features/VirtualGuestApi.java     |  135 +-
 ...VirtualGuestBlockDeviceTemplateGroupApi.java |   58 +
 .../handlers/SoftLayerErrorHandler.java         |    5 +-
 .../predicates/ProductItemPredicates.java       |  154 --
 .../predicates/ProductPackagePredicates.java    |   41 -
 .../softlayer/reference/SoftLayerConstants.java |   37 +-
 .../org/jclouds/softlayer/SoftLayerApiTest.java |   53 -
 .../softlayer/SoftLayerProviderTest.java        |    3 +-
 .../binders/ProductOrderToJsonTest.java         |   92 --
 .../softlayer/binders/TagToJsonTest.java        |   51 +
 .../binders/VirtualGuestToJsonTest.java         |  122 ++
 .../SoftLayerComputeServiceAdapterLiveTest.java |   50 +-
 .../SoftLayerComputeServiceContextLiveTest.java |  107 ++
 .../SoftLayerComputeServiceLiveTest.java        |   15 +-
 .../SoftLayerTemplateBuilderLiveTest.java       |   98 +-
 .../functions/DatacenterToLocationTest.java     |   19 +-
 .../functions/OperatingSystemToImageTest.java   |   57 +
 .../functions/ProductItemToImageTest.java       |  262 ----
 .../compute/functions/ProductItemsTest.java     |  141 --
 .../functions/ProductItemsToHardwareTest.java   |  155 --
 .../functions/VirtualGuestToHardwareTest.java   |   61 +
 .../functions/VirtualGuestToImageTest.java      |  119 ++
 .../VirtualGuestToNodeMetadataTest.java         |  229 +--
 .../internal/OperatingSystemsTest.java          |   50 +
 .../jclouds/softlayer/domain/AddressTest.java   |    3 -
 .../features/AccountApiExpectTest.java          |   94 ++
 .../softlayer/features/AccountApiLiveTest.java  |   50 +-
 .../softlayer/features/AccountApiTest.java      |   53 -
 .../features/BaseSoftLayerApiExpectTest.java    |   31 +
 .../features/BaseSoftLayerApiLiveTest.java      |    1 +
 .../features/BaseSoftLayerApiTest.java          |   40 -
 .../features/DatacenterApiExpectTest.java       |   96 ++
 .../features/DatacenterApiLiveTest.java         |   59 +-
 .../softlayer/features/DatacenterApiTest.java   |   83 --
 .../features/ProductPackageApiLiveTest.java     |  216 ---
 .../features/ProductPackageApiTest.java         |   53 -
 .../SoftwareDescriptionApiExpectTest.java       |   58 +
 .../SoftwareDescriptionApiLiveTest.java         |   43 +
 .../features/VirtualGuestApiExpectTest.java     |  262 +++-
 .../features/VirtualGuestApiLiveTest.java       |  220 +--
 .../softlayer/features/VirtualGuestApiTest.java |  173 ---
 ...stBlockDeviceTemplateGroupApiExpectTest.java |   62 +
 ...uestBlockDeviceTemplateGroupApiLiveTest.java |   41 +
 .../internal/BaseSoftLayerParseTest.java        |   33 +
 .../parse/CreateVirtualGuestResponseTest.java   |   60 +
 .../parse/GetAllObjectsResponseTest.java        |   65 +
 .../GetCreateObjectOptionsResponseTest.java     |  105 ++
 .../parse/GetDatacenterResponseTest.java        |   65 +
 ...stBlockDeviceTemplateGroupsResponseTest.java |  134 ++
 .../parse/GetVirtualGuestResponseTest.java      |   68 +
 .../parse/ListDatacentersResponseTest.java      |  117 ++
 .../parse/ListPublicImagesResponseTest.java     |  111 ++
 .../parse/ListVirtualGuestsResponseTest.java    |   73 +
 .../softlayer/parse/ParseBadVirtualGuest.java   |   59 -
 .../softlayer/parse/ParseProductOrderTest.java  |  101 --
 .../parse/ParseVirtualGuestHaltedTest.java      |   69 -
 .../parse/ParseVirtualGuestPausedTest.java      |   69 -
 .../parse/ParseVirtualGuestRunningTest.java     |   69 -
 .../ParseVirtualGuestWithNoPasswordTest.java    |   65 -
 .../predicates/ProductItemPredicatesTest.java   |  101 --
 .../ProductPackagePredicatesTest.java           |   42 -
 ...count_get_block_devices_template_groups.json |  110 ++
 .../src/test/resources/account_list.json        |   24 +
 .../container_virtual_guest_configuration.json  |   93 ++
 .../src/test/resources/datacenter_get.json      |   30 +
 .../src/test/resources/datacenter_list.json     |   72 +
 .../softlayer/src/test/resources/log4j.xml      |  151 --
 .../softlayer/src/test/resources/logback.xml    |   34 +
 .../test/resources/product_order_template.json  | 1337 ------------------
 .../resources/software_description_list.json    |   21 +
 ...tBlockDeviceTemplateGroup_public_images.json |   98 ++
 .../resources/virtual_guest_bad_halted.json     |    4 -
 .../test/resources/virtual_guest_create.json    |    1 +
 .../virtual_guest_create_response.json          |   19 +
 .../src/test/resources/virtual_guest_get.json   |   22 +
 .../resources/virtual_guest_good_halted.json    |  117 --
 .../resources/virtual_guest_no_password.json    |   74 -
 .../test/resources/virtual_guest_paused.json    |  117 --
 .../test/resources/virtual_guest_running.json   |  117 --
 .../test/resources/virtual_guest_set_tags.json  |    1 +
 .../virtual_guest_set_tags_response.json        |    1 +
 133 files changed, 7494 insertions(+), 6721 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/pom.xml
----------------------------------------------------------------------
diff --git a/providers/softlayer/pom.xml b/providers/softlayer/pom.xml
index 6eb7dba..c6b849d 100644
--- a/providers/softlayer/pom.xml
+++ b/providers/softlayer/pom.xml
@@ -82,15 +82,20 @@
     </dependency>
     <dependency>
       <groupId>org.apache.jclouds.driver</groupId>
-      <artifactId>jclouds-log4j</artifactId>
+      <artifactId>jclouds-sshj</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
     <dependency>
-      <groupId>org.apache.jclouds.driver</groupId>
-      <artifactId>jclouds-sshj</artifactId>
-      <version>${project.version}</version>
-      <scope>test</scope>
+        <groupId>org.apache.jclouds.driver</groupId>
+        <artifactId>jclouds-slf4j</artifactId>
+        <version>${project.version}</version>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>ch.qos.logback</groupId>
+        <artifactId>logback-classic</artifactId>
+        <scope>test</scope>
     </dependency>
   </dependencies>
   <profiles>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApi.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApi.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApi.java
index d1e7f3d..5c57918 100644
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApi.java
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApi.java
@@ -16,42 +16,43 @@
  */
 package org.jclouds.softlayer;
 
-import java.io.Closeable;
-
 import org.jclouds.rest.annotations.Delegate;
 import org.jclouds.softlayer.features.AccountApi;
 import org.jclouds.softlayer.features.DatacenterApi;
-import org.jclouds.softlayer.features.ProductPackageApi;
+import org.jclouds.softlayer.features.SoftwareDescriptionApi;
 import org.jclouds.softlayer.features.VirtualGuestApi;
+import org.jclouds.softlayer.features.VirtualGuestBlockDeviceTemplateGroupApi;
+
+import java.io.Closeable;
 
-/**
- * Provides synchronous access to SoftLayer.
- * <p/>
- * 
- * @see <a href="http://sldn.softlayer.com/article/REST" />
- */
 public interface SoftLayerApi extends Closeable {
 
    /**
-    * Provides synchronous access to VirtualGuest features.
+    * Provides access to VirtualGuest features.
     */
    @Delegate
    VirtualGuestApi getVirtualGuestApi();
 
    /**
-    * Provides synchronous access to Datacenter features.
+    * Provides access to Datacenter features.
     */
    @Delegate
    DatacenterApi getDatacenterApi();
 
    /**
-    * Provides synchronous access to ProductPackage features.
+    * Provides access to SoftwareDescription features.
+    */
+   @Delegate
+   SoftwareDescriptionApi getSoftwareDescriptionApi();
+
+   /**
+    * Provides access to VirtualGuestBlockDeviceTemplateGroup features.
     */
    @Delegate
-   ProductPackageApi getProductPackageApi();
+   VirtualGuestBlockDeviceTemplateGroupApi getVirtualGuestBlockDeviceTemplateGroupApi();
 
    /**
-    * Provides synchronous access to Account features.
+    * Provides access to Account features.
     */
    @Delegate
    AccountApi getAccountApi();

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApiMetadata.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApiMetadata.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApiMetadata.java
index edba330..f6b8736 100644
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApiMetadata.java
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerApiMetadata.java
@@ -17,7 +17,7 @@
 package org.jclouds.softlayer;
 
 import static org.jclouds.reflect.Reflection2.typeToken;
-
+import static org.jclouds.softlayer.reference.SoftLayerConstants.SOFTLAYER_PROVIDER_NAME;
 import java.net.URI;
 import java.util.Properties;
 
@@ -30,11 +30,10 @@ import com.google.common.collect.ImmutableSet;
 import com.google.inject.Module;
 
 /**
- * Implementation of {@link ApiMetadata} for API
+ * Implementation of {@link org.jclouds.apis.ApiMetadata} for API
  */
 public class SoftLayerApiMetadata extends BaseHttpApiMetadata<SoftLayerApi> {
 
-
    @Override
    public Builder toBuilder() {
       return new Builder().fromApiMetadata(this);
@@ -57,18 +56,18 @@ public class SoftLayerApiMetadata extends BaseHttpApiMetadata<SoftLayerApi> {
 
    public static class Builder extends BaseHttpApiMetadata.Builder<SoftLayerApi, Builder> {
 
-      @SuppressWarnings("deprecation")
       protected Builder() {
-         id("softlayer")
-         .name("SoftLayer API")
-         .identityName("API Username")
-         .credentialName("API Key")
-         .documentation(URI.create("http://sldn.softlayer.com/article/REST"))
-         .version("3")
-         .defaultEndpoint("https://api.softlayer.com/rest")
-         .defaultProperties(SoftLayerApiMetadata.defaultProperties())
-         .view(typeToken(ComputeServiceContext.class))
-         .defaultModules(ImmutableSet.<Class<? extends Module>>of(SoftLayerHttpApiModule.class, SoftLayerComputeServiceContextModule.class));
+         id(SOFTLAYER_PROVIDER_NAME)
+                 .name("SoftLayer API")
+                 .identityName("API Username")
+                 .credentialName("API Key")
+                 .documentation(URI.create("http://sldn.softlayer.com/article/REST"))
+                 .version("3")
+                 .defaultEndpoint("https://api.softlayer.com/rest")
+                 .defaultProperties(SoftLayerApiMetadata.defaultProperties())
+                 .view(typeToken(ComputeServiceContext.class))
+                 .defaultModules(ImmutableSet.<Class<? extends Module>>of(SoftLayerHttpApiModule.class,
+                         SoftLayerComputeServiceContextModule.class)).build();
       }
 
       @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerProviderMetadata.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerProviderMetadata.java
index 08cfc9b..e152eb4 100644
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerProviderMetadata.java
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/SoftLayerProviderMetadata.java
@@ -16,25 +16,19 @@
  */
 package org.jclouds.softlayer;
 
-import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
-import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX;
-import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE;
-import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY;
-import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME;
-import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED;
-import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES;
+import org.jclouds.providers.ProviderMetadata;
+import org.jclouds.providers.internal.BaseProviderMetadata;
 
 import java.net.URI;
 import java.util.Properties;
 
-import org.jclouds.providers.ProviderMetadata;
-import org.jclouds.providers.internal.BaseProviderMetadata;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableSet;
+import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
+import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_INCLUDE_PUBLIC_IMAGES;
+import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_ACTIVE_TRANSACTIONS_DELAY;
+import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY;
 
 /**
- * Implementation of {@link org.jclouds.types.ProviderMetadata} for SoftLayer.
+ * Implementation of {@link org.jclouds.providers.ProviderMetadata} for SoftLayer.
  */
 public class SoftLayerProviderMetadata extends BaseProviderMetadata {
 
@@ -58,27 +52,9 @@ public class SoftLayerProviderMetadata extends BaseProviderMetadata {
    public static Properties defaultProperties() {
       Properties properties = new Properties();
       properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY, "" + 60 * 60 * 1000);
-      properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME, "Cloud Server");
-      // ex: for private (ex. don't share hardware) use "Private [0-9]+ x ([.0-9]+) GHz Core[s]?"
-      // ex: for private and public use ".*[0-9]+ x ([.0-9]+) GHz Core[s]?"
-      properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_CPU_REGEX, "[0-9]+ x ([0-9.]+) GHz Core[s]?");
-      // SAN or LOCAL
-      properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_DISK0_TYPE, "LOCAL");
-      // 10, 100, 1000
-      properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PORT_SPEED, "10");
-      ImmutableSet.Builder<String> prices = ImmutableSet.builder();
-      prices.add("21"); // 1 IP Address
-      prices.add("55"); // Host Ping: categoryCode: monitoring, notification
-      prices.add("57"); // Email and Ticket: categoryCode: notification
-      prices.add("58"); // Automated Notification: categoryCode: response
-      prices.add("1800"); // 0 GB Bandwidth: categoryCode: bandwidth
-      prices.add("905"); // Reboot / Remote Console: categoryCode: remote_management
-      prices.add("418"); // Nessus Vulnerability Assessment & Reporting: categoryCode:
-                         // vulnerability_scanner
-      prices.add("420"); // Unlimited SSL VPN Users & 1 PPTP VPN User per account: categoryCode:
-                         // vpn_management
-      properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES, Joiner.on(',').join(prices.build()));
-      properties.setProperty(TEMPLATE, "osFamily=UBUNTU,osVersionMatches=1[012].[01][04],os64Bit=true,osDescriptionMatches=.*Minimal Install.*");
+      properties.setProperty(PROPERTY_SOFTLAYER_VIRTUALGUEST_ACTIVE_TRANSACTIONS_DELAY, "" + 3 * 60 * 1000);
+      properties.setProperty(PROPERTY_SOFTLAYER_INCLUDE_PUBLIC_IMAGES, "false");
+      properties.setProperty(TEMPLATE, "osFamily=UBUNTU,osVersionMatches=1[012].[01][04],os64Bit=true");
       return properties;
    }
 
@@ -90,7 +66,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", "HK", "NSFTW-IL")  // NSFTW-IL is a weird isoCode returned by Softlayer
          .endpoint("https://api.softlayer.com/rest")
          .defaultProperties(SoftLayerProviderMetadata.defaultProperties());
       }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/ProductOrderToJson.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/ProductOrderToJson.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/ProductOrderToJson.java
deleted file mode 100644
index 35a85a2..0000000
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/ProductOrderToJson.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.binders;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Set;
-
-import javax.inject.Inject;
-
-import org.jclouds.http.HttpRequest;
-import org.jclouds.json.Json;
-import org.jclouds.rest.Binder;
-import org.jclouds.softlayer.domain.ProductItemPrice;
-import org.jclouds.softlayer.domain.ProductOrder;
-import org.jclouds.softlayer.domain.VirtualGuest;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-
-/**
- * Converts a ProductOrder into a json string valid for placing an order via the softlayer api The
- * String is set into the payload of the HttpRequest
- */
-public class ProductOrderToJson implements Binder {
-
-   private Json json;
-
-   @Inject
-   public ProductOrderToJson(Json json) {
-      this.json = json;
-   }
-
-   @Override
-   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
-      checkNotNull(input, "order");
-      ProductOrder order = ProductOrder.class.cast(input);
-      request.setPayload(buildJson(order));
-      return request;
-   }
-
-   /**
-    * Builds a Json string suitable for sending to the softlayer api
-    * 
-    * @param order
-    * @return
-    */
-   String buildJson(ProductOrder order) {
-
-      Iterable<Price> prices = Iterables.transform(order.getPrices(), new Function<ProductItemPrice, Price>() {
-         @Override
-         public Price apply(ProductItemPrice productItemPrice) {
-            return new Price(productItemPrice.getId());
-         }
-      });
-
-      Iterable<HostnameAndDomain> hosts = Iterables.transform(order.getVirtualGuests(),
-               new Function<VirtualGuest, HostnameAndDomain>() {
-                  @Override
-                  public HostnameAndDomain apply(VirtualGuest virtualGuest) {
-                     return new HostnameAndDomain(virtualGuest.getHostname(), virtualGuest.getDomain());
-                  }
-               });
-
-      OrderData data = new OrderData(order.getPackageId(), order.getLocation(), Sets.newLinkedHashSet(prices), Sets
-               .newLinkedHashSet(hosts), order.getQuantity(), order.getUseHourlyPricing());
-
-      return json.toJson(ImmutableMap.of("parameters", ImmutableList.<OrderData> of(data)));
-   }
-
-   @SuppressWarnings("unused")
-   private static class OrderData {
-      private String complexType = "SoftLayer_Container_Product_Order_Virtual_Guest";
-      private long packageId = -1;
-      private String location;
-      private Set<Price> prices;
-      private Set<HostnameAndDomain> virtualGuests;
-      private long quantity;
-      private boolean useHourlyPricing;
-
-      public OrderData(long packageId, String location, Set<Price> prices, Set<HostnameAndDomain> virtualGuests,
-               long quantity, boolean useHourlyPricing) {
-         this.packageId = packageId;
-         this.location = location;
-         this.prices = prices;
-         this.virtualGuests = virtualGuests;
-         this.quantity = quantity;
-         this.useHourlyPricing = useHourlyPricing;
-      }
-
-   }
-
-   @SuppressWarnings("unused")
-   private static class HostnameAndDomain {
-      private String hostname;
-      private String domain;
-
-      public HostnameAndDomain(String hostname, String domain) {
-         this.hostname = hostname;
-         this.domain = domain;
-      }
-
-   }
-
-   @SuppressWarnings("unused")
-   private static class Price {
-      private long id;
-
-      public Price(long id) {
-         this.id = id;
-      }
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/TagToJson.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/TagToJson.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/TagToJson.java
new file mode 100644
index 0000000..bea654c
--- /dev/null
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/TagToJson.java
@@ -0,0 +1,60 @@
+/*
+ * 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.binders;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.json.Json;
+import org.jclouds.rest.Binder;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Converts a Tag into a json string valid for creating a CCI via softlayer api
+ * The string is set into the payload of the HttpRequest
+ * 
+ */
+@Singleton
+public class TagToJson implements Binder {
+
+   private final Json json;
+
+   @Inject
+   public TagToJson(Json json) {
+      this.json = checkNotNull(json, "json");
+   }
+
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+      checkArgument(input instanceof Set);
+      Set<String> tags = Set.class.cast(checkNotNull(input, "input"));
+      request.setPayload(buildJson(tags));
+      return request;
+   }
+
+   String buildJson(Set<String> tags) {
+      return json.toJson(ImmutableMap.of("parameters", ImmutableSet.of(Joiner.on(",").join(tags))));
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/VirtualGuestToJson.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/VirtualGuestToJson.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/VirtualGuestToJson.java
new file mode 100644
index 0000000..9a14e5a
--- /dev/null
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/binders/VirtualGuestToJson.java
@@ -0,0 +1,201 @@
+/*
+ * 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.binders;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedSet;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.json.Json;
+import org.jclouds.rest.Binder;
+import org.jclouds.softlayer.domain.VirtualGuest;
+import org.jclouds.softlayer.domain.VirtualGuestBlockDevice;
+import org.jclouds.softlayer.domain.VirtualGuestNetworkComponent;
+
+import javax.inject.Inject;
+import java.util.Comparator;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Converts a VirtualGuest into a json string valid for creating a CCI via softlayer api
+ * The string is set into the payload of the HttpRequest
+ * 
+ */
+public class VirtualGuestToJson implements Binder {
+
+   private final Json json;
+
+   @Inject
+   public VirtualGuestToJson(Json json) {
+      this.json = checkNotNull(json, "json");
+   }
+
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Object input) {
+      checkArgument(input instanceof VirtualGuest);
+      VirtualGuest virtualGuest = VirtualGuest.class.cast(checkNotNull(input, "input"));
+      request.setPayload(buildJson(virtualGuest));
+      return request;
+   }
+
+   /**
+    * Builds a Json string suitable for sending to the softlayer api
+    *
+    * @param virtualGuest
+    * @return String
+    */
+   String buildJson(VirtualGuest virtualGuest) {
+      TemplateObject templateObject = null;
+      String hostname = checkNotNull(virtualGuest.getHostname(), "hostname");
+      String domain = checkNotNull(virtualGuest.getDomain(), "domain");
+      int startCpus = checkNotNull(virtualGuest.getStartCpus(), "startCpus");
+      int maxMemory = checkNotNull(virtualGuest.getMaxMemory(), "maxMemory");
+      boolean localDiskFlag = checkNotNull(virtualGuest.isLocalDiskFlag(), "localDiskFlag");
+      String datacenterName = checkNotNull(virtualGuest.getDatacenter().getName(), "datacenterName");
+      Set<NetworkComponent> networkComponents = getNetworkComponents(virtualGuest);
+      if (virtualGuest.getOperatingSystem() != null) {
+         String operatingSystemReferenceCode = checkNotNull(virtualGuest.getOperatingSystem()
+                 .getOperatingSystemReferenceCode(), "operatingSystemReferenceCode");
+         templateObject = new TemplateObject(hostname, domain, startCpus, maxMemory, true,
+                 operatingSystemReferenceCode, null, localDiskFlag, new Datacenter(datacenterName), networkComponents,
+                 getBlockDevices(virtualGuest));
+      } else if(virtualGuest.getVirtualGuestBlockDeviceTemplateGroup() != null) {
+         String globalIdentifier = checkNotNull(virtualGuest.getVirtualGuestBlockDeviceTemplateGroup()
+                 .getGlobalIdentifier(), "blockDeviceTemplateGroup.globalIdentifier");
+         templateObject = new TemplateObject(hostname, domain, startCpus, maxMemory, true, null,
+                 new BlockDeviceTemplateGroup(globalIdentifier), localDiskFlag, new Datacenter(datacenterName),
+                 networkComponents, null);
+      }
+      return json.toJson(ImmutableMap.of("parameters", ImmutableList.of(templateObject)));
+   }
+
+   private Set<BlockDevice> getBlockDevices(VirtualGuest virtualGuest) {
+      if (virtualGuest.getVirtualGuestBlockDevices() == null) {
+         return null;
+      }
+      ImmutableSortedSet.Builder<BlockDevice> blockDevices = ImmutableSortedSet.orderedBy(new BlockDevicesComparator());
+      for (VirtualGuestBlockDevice blockDevice : virtualGuest.getVirtualGuestBlockDevices()) {
+         blockDevices.add(new BlockDevice(blockDevice.getDevice(), blockDevice.getVirtualDiskImage().getCapacity()));
+      }
+      return blockDevices.build();
+   }
+
+   private Set<NetworkComponent> getNetworkComponents(VirtualGuest virtualGuest) {
+      if (virtualGuest.getVirtualGuestNetworkComponents() == null) {
+         return null;
+      }
+      ImmutableSet.Builder networkComponents = ImmutableSet.builder();
+      for (VirtualGuestNetworkComponent networkComponent : virtualGuest.getVirtualGuestNetworkComponents()) {
+         networkComponents.add(new NetworkComponent(networkComponent.getSpeed()));
+      }
+      return networkComponents.build();
+   }
+
+   private static class TemplateObject {
+      private final String hostname;
+      private final String domain;
+      private final int startCpus;
+      private final int maxMemory;
+      private final boolean hourlyBillingFlag;
+      private final BlockDeviceTemplateGroup blockDeviceTemplateGroup;
+      private final String operatingSystemReferenceCode;
+      private final boolean localDiskFlag;
+      private final Datacenter datacenter;
+      private final Set<NetworkComponent> networkComponents;
+      private final Set<BlockDevice> blockDevices;
+
+      private TemplateObject(String hostname, String domain, int startCpus, int maxMemory, boolean hourlyBillingFlag,
+                         String operatingSystemReferenceCode, BlockDeviceTemplateGroup blockDeviceTemplateGroup,
+                         boolean localDiskFlag, Datacenter datacenter, Set<NetworkComponent> networkComponents,
+                         Set<BlockDevice> blockDevices) {
+         this.hostname = hostname;
+         this.domain = domain;
+         this.startCpus = startCpus;
+         this.maxMemory = maxMemory;
+         this.hourlyBillingFlag = hourlyBillingFlag;
+         this.operatingSystemReferenceCode = operatingSystemReferenceCode;
+         this.blockDeviceTemplateGroup = blockDeviceTemplateGroup;
+         this.localDiskFlag = localDiskFlag;
+         this.datacenter = datacenter;
+         this.networkComponents = networkComponents;
+         this.blockDevices = blockDevices;
+      }
+   }
+
+   private class Datacenter {
+      private String name;
+
+      private Datacenter(String name) {
+         this.name = name;
+      }
+   }
+
+   private class NetworkComponent {
+      private int maxSpeed;
+
+      private NetworkComponent(int maxSpeed) {
+         this.maxSpeed = maxSpeed;
+      }
+   }
+
+   private class BlockDevice {
+      private String device;
+      private DiskImage diskImage;
+
+      public String getDevice() {
+         return device;
+      }
+
+      public DiskImage getDiskImage() {
+         return diskImage;
+      }
+
+      private BlockDevice(String device, float diskImageCapacity) {
+         this.device = device;
+         this.diskImage = new DiskImage(diskImageCapacity);
+      }
+   }
+
+   private class DiskImage {
+      private float capacity;
+
+      private DiskImage(float capacity) {
+         this.capacity = capacity;
+      }
+   }
+
+   private class BlockDeviceTemplateGroup {
+      private String globalIdentifier;
+
+      private BlockDeviceTemplateGroup(String globalIdentifier) {
+         this.globalIdentifier = globalIdentifier;
+      }
+   }
+
+   private class BlockDevicesComparator implements Comparator<BlockDevice> {
+
+         @Override
+         public int compare(BlockDevice b1, BlockDevice b2) {
+            return Integer.valueOf(b1.getDevice()).compareTo(Integer.valueOf(b2.getDevice()));
+         }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/config/SoftLayerComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/config/SoftLayerComputeServiceContextModule.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/config/SoftLayerComputeServiceContextModule.java
index 07a2f8f..e2bf26a 100644
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/config/SoftLayerComputeServiceContextModule.java
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/config/SoftLayerComputeServiceContextModule.java
@@ -16,13 +16,7 @@
  */
 package org.jclouds.softlayer.compute.config;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Iterables.find;
 import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
-import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
-import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME;
-import static org.jclouds.softlayer.reference.SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES;
-
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -32,94 +26,75 @@ import javax.inject.Singleton;
 import org.jclouds.collect.Memoized;
 import org.jclouds.compute.ComputeServiceAdapter;
 import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
+import org.jclouds.compute.domain.Hardware;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.options.TemplateOptions;
 import org.jclouds.domain.Location;
+import org.jclouds.functions.IdentityFunction;
 import org.jclouds.rest.AuthorizationException;
 import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
 import org.jclouds.softlayer.SoftLayerApi;
 import org.jclouds.softlayer.compute.functions.DatacenterToLocation;
-import org.jclouds.softlayer.compute.functions.ProductItemToImage;
-import org.jclouds.softlayer.compute.functions.ProductItemsToHardware;
+import org.jclouds.softlayer.compute.functions.OperatingSystemToImage;
+import org.jclouds.softlayer.compute.functions.VirtualGuestToHardware;
 import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata;
 import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
 import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
+import org.jclouds.softlayer.domain.ContainerVirtualGuestConfiguration;
 import org.jclouds.softlayer.domain.Datacenter;
-import org.jclouds.softlayer.domain.ProductItem;
-import org.jclouds.softlayer.domain.ProductItemPrice;
-import org.jclouds.softlayer.domain.ProductPackage;
+import org.jclouds.softlayer.domain.OperatingSystem;
 import org.jclouds.softlayer.domain.VirtualGuest;
-import org.jclouds.softlayer.features.AccountApi;
-import org.jclouds.softlayer.features.ProductPackageApi;
 
 import com.google.common.base.Function;
 import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
 import com.google.common.base.Supplier;
-import com.google.common.collect.Iterables;
 import com.google.inject.Provides;
 import com.google.inject.TypeLiteral;
 
 public class SoftLayerComputeServiceContextModule extends
-         ComputeServiceAdapterContextModule<VirtualGuest, Iterable<ProductItem>, ProductItem, Datacenter> {
+         ComputeServiceAdapterContextModule<VirtualGuest, Hardware, OperatingSystem, Datacenter> {
 
    @Override
    protected void configure() {
       super.configure();
-      bind(new TypeLiteral<ComputeServiceAdapter<VirtualGuest, Iterable<ProductItem>, ProductItem, Datacenter>>() {
+      bind(new TypeLiteral<ComputeServiceAdapter<VirtualGuest, Hardware, OperatingSystem, Datacenter>>() {
       }).to(SoftLayerComputeServiceAdapter.class);
       bind(new TypeLiteral<Function<VirtualGuest, NodeMetadata>>() {
       }).to(VirtualGuestToNodeMetadata.class);
-      bind(new TypeLiteral<Function<ProductItem, org.jclouds.compute.domain.Image>>() {
-      }).to(ProductItemToImage.class);
-      bind(new TypeLiteral<Function<Iterable<ProductItem>, org.jclouds.compute.domain.Hardware>>() {
-      }).to(ProductItemsToHardware.class);
+      bind(new TypeLiteral<Function<OperatingSystem, org.jclouds.compute.domain.Image>>() {
+      }).to(OperatingSystemToImage.class);
+      bind(new TypeLiteral<Function<Hardware, Hardware>>() {
+      }).to(Class.class.cast(IdentityFunction.class));
+      bind(new TypeLiteral<Function<VirtualGuest, org.jclouds.compute.domain.Hardware>>() {
+      }).to(VirtualGuestToHardware.class);
       bind(new TypeLiteral<Function<Datacenter, Location>>() {
       }).to(DatacenterToLocation.class);
       bind(TemplateOptions.class).to(SoftLayerTemplateOptions.class);
       // to have the compute service adapter override default locations
-      install(new LocationsFromComputeServiceAdapterModule<VirtualGuest, Iterable<ProductItem>, ProductItem, Datacenter>(){});
+      install(new LocationsFromComputeServiceAdapterModule<VirtualGuest, Hardware, OperatingSystem, Datacenter>(){});
+
    }
 
-   /**
-    * Many requests need the same productPackage, which is in this case the package for virtual
-    * guests. We may at some point need to make an annotation qualifying it as such. ex. @VirtualGuest
-    */
    @Provides
    @Singleton
    @Memoized
-   public Supplier<ProductPackage> getProductPackage(AtomicReference<AuthorizationException> authException,
-            @Named(PROPERTY_SESSION_INTERVAL) long seconds, final SoftLayerApi client,
-            @Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME) final String virtualGuestPackageName) {
+   public Supplier<ContainerVirtualGuestConfiguration> getCreateObjectOptions(
+           AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
+           final SoftLayerApi api) {
       return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
-               new Supplier<ProductPackage>() {
-                  @Override
-                  public ProductPackage get() {
-                     AccountApi accountApi = client.getAccountApi();
-                     ProductPackageApi productPackageApi = client.getProductPackageApi();
-                     ProductPackage p = find(accountApi.getActivePackages(), named(virtualGuestPackageName));
-                     return productPackageApi.getProductPackage(p.getId());
-                  }
-                  
-                  @Override
-                  public String toString() {
-                     return Objects.toStringHelper(client).add("method", "accountClient.getActivePackages")
-                                                          .add("method", "productPackageClient.getProductPackage").toString();
-                  }
-               }, seconds, TimeUnit.SECONDS);
-   }
+              new Supplier<ContainerVirtualGuestConfiguration>() {
+                 @Override
+                 public ContainerVirtualGuestConfiguration get() {
+                    return api.getVirtualGuestApi().getCreateObjectOptions();
+                 }
 
-   // TODO: check the prices really do exist
-   @Provides
-   @Singleton
-   public Iterable<ProductItemPrice> prices(@Named(PROPERTY_SOFTLAYER_VIRTUALGUEST_PRICES) String prices) {
-      return Iterables.transform(Splitter.on(',').split(checkNotNull(prices, "prices")),
-               new Function<String, ProductItemPrice>() {
-                  @Override
-                  public ProductItemPrice apply(String arg0) {
-                     return ProductItemPrice.builder().id(Integer.parseInt(arg0)).build();
-                  }
-               });
+                 @Override
+                 public String toString() {
+                    return Objects.toStringHelper(api)
+                            .add("method", "virtualGuestApi.getCreateObjectOptions")
+                            .toString();
+                 }
+              }, seconds, TimeUnit.SECONDS);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/DatacenterToLocation.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/DatacenterToLocation.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/DatacenterToLocation.java
index 6890eca..106c584 100644
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/DatacenterToLocation.java
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/DatacenterToLocation.java
@@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Strings.nullToEmpty;
 
 import javax.inject.Inject;
+import javax.inject.Singleton;
 
 import org.jclouds.domain.Location;
 import org.jclouds.domain.LocationBuilder;
@@ -36,7 +37,8 @@ import com.google.common.collect.Iterables;
 /**
  * Converts an Datacenter into a Location.
  */
-public class DatacenterToLocation implements Function<Datacenter, Location> {
+@Singleton
+public class  DatacenterToLocation implements Function<Datacenter,Location> {
    private final JustProvider provider;
 
    // allow us to lazy discover the provider of a resource
@@ -47,12 +49,12 @@ public class DatacenterToLocation implements Function<Datacenter, Location> {
    
     @Override
     public Location apply(Datacenter datacenter) {
-        return new LocationBuilder().scope(LocationScope.ZONE)
-                                    .metadata(ImmutableMap.<String, Object>of())
+        return new LocationBuilder().id(datacenter.getName())
                                     .description(datacenter.getLongName())
-                                    .id(Long.toString(datacenter.getId()))
+                                    .scope(LocationScope.ZONE)
                                     .iso3166Codes(createIso3166Codes(datacenter.getLocationAddress()))
                                     .parent(Iterables.getOnlyElement(provider.get()))
+                                    .metadata(ImmutableMap.<String, Object>of("name", datacenter.getName()))
                                     .build();
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/OperatingSystemToImage.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/OperatingSystemToImage.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/OperatingSystemToImage.java
new file mode 100644
index 0000000..19dfd2a
--- /dev/null
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/OperatingSystemToImage.java
@@ -0,0 +1,92 @@
+/*
+ * 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.compute.functions;
+
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.softlayer.compute.functions.internal.OperatingSystems;
+import org.jclouds.softlayer.domain.OperatingSystem;
+import org.jclouds.softlayer.domain.SoftwareDescription;
+import org.jclouds.softlayer.domain.SoftwareLicense;
+
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+
+@Singleton
+public class OperatingSystemToImage implements Function<OperatingSystem, Image> {
+
+   private static final String UNRECOGNIZED = "UNRECOGNIZED";
+
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+
+   @Override
+   public Image apply(OperatingSystem operatingSystem) {
+      checkNotNull(operatingSystem, "operatingSystem");
+      final SoftwareLicense defaultSoftwareLicense = SoftwareLicense.builder().softwareDescription(SoftwareDescription.builder().build()).build();
+      SoftwareLicense softwareLicense = fromNullable(operatingSystem.getSoftwareLicense()).or(defaultSoftwareLicense);
+      Optional<String> optOSReferenceCode = fromNullable(softwareLicense.getSoftwareDescription().getReferenceCode());
+      Optional<String> optVersion = fromNullable(softwareLicense.getSoftwareDescription().getVersion());
+      Optional<String> optLongDescription = fromNullable(softwareLicense.getSoftwareDescription().getLongDescription());
+      OsFamily osFamily = OsFamily.UNRECOGNIZED;
+      String osVersion = UNRECOGNIZED;
+      Integer bits = null;
+      if(optOSReferenceCode.isPresent()) {
+         String operatingSystemReferenceCode = optOSReferenceCode.get();
+         osFamily = OperatingSystems.osFamily().apply(operatingSystemReferenceCode);
+         bits = OperatingSystems.bits().apply(operatingSystemReferenceCode);
+      }
+      if(optVersion.isPresent()) {
+         osVersion = OperatingSystems.version().apply(optVersion.get());
+      }
+      if (osFamily == OsFamily.UNRECOGNIZED) {
+         logger.debug("Cannot determine os family for item: %s", operatingSystem);
+      }
+      if (osVersion == null) {
+         logger.debug("Cannot determine os version for item: %s", operatingSystem);
+      }
+      if (bits == null) {
+         logger.debug("Cannot determine os bits for item: %s", operatingSystem);
+      }
+
+      org.jclouds.compute.domain.OperatingSystem os = org.jclouds.compute.domain.OperatingSystem.builder()
+              .description(optLongDescription.or(UNRECOGNIZED))
+              .family(osFamily)
+              .version(osVersion)
+              .is64Bit(Objects.equal(bits, 64))
+              .build();
+
+      return new ImageBuilder()
+              .ids(operatingSystem.getId())
+              .description(optOSReferenceCode.or(UNRECOGNIZED))
+              .operatingSystem(os)
+              .status(Image.Status.AVAILABLE)
+              .build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java
deleted file mode 100644
index ff94332..0000000
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemToImage.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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.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 org.jclouds.compute.domain.Image;
-import org.jclouds.compute.domain.ImageBuilder;
-import org.jclouds.compute.domain.OperatingSystem;
-import org.jclouds.compute.domain.OsFamily;
-import org.jclouds.compute.reference.ComputeServiceConstants;
-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;
-
-@Singleton
-public class ProductItemToImage implements Function<ProductItem, Image> {
-
-   /**
-    * Pattern to capture the number of bits e.g. "a (32 bit) os"
-    */
-   private static final Pattern OS_BITS_PATTERN = Pattern.compile(".*\\((\\d+) ?bit\\).*");
-
-   private static final String CENTOS = "CentOS";
-   private static final String DEBIAN = "Debian GNU/Linux";
-   private static final String FEDORA = "Fedora Release";
-   private static final String RHEL = "Red Hat Enterprise Linux";
-   private static final String UBUNTU = "Ubuntu Linux";
-   private static final String WINDOWS = "Windows Server";
-   private static final String CLOUD_LINUX = "CloudLinux";
-
-   @Resource
-   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
-   protected Logger logger = Logger.NULL;
-
-   @Override
-   public Image apply(ProductItem productItem) {
-      checkNotNull(productItem, "productItem");
-      String description = checkNotNull(productItem.getDescription(), "productItem.description");
-
-      OsFamily osFamily = osFamily().apply(description);
-      if (osFamily == OsFamily.UNRECOGNIZED) {
-         logger.debug("Cannot determine os family for item: %s", productItem);
-      }
-      Integer bits = osBits().apply(description);
-      if (bits == null) {
-         logger.debug("Cannot determine os bits for item: %s", productItem);
-      }
-      String osVersion = osVersion().apply(description);
-      if (osVersion == null) {
-         logger.debug("Cannot determine os version for item: %s", productItem);
-      }
-      OperatingSystem os = OperatingSystem.builder()
-            .description(description)
-            .family(osFamily)
-            .version(osVersion)
-            .is64Bit(Objects.equal(bits, 64))
-            .build();
-
-      return new ImageBuilder()
-            .ids(imageId().apply(productItem))
-            .description(description)
-            .operatingSystem(os)
-            .status(Image.Status.AVAILABLE)
-            .build();
-   }
-
-   /**
-    * Parses the item description to determine the OSFamily
-    *
-    * @return the @see OsFamily or OsFamily.UNRECOGNIZED
-    */
-   public static Function<String, OsFamily> osFamily() {
-      return new Function<String, OsFamily>() {
-         @Override
-         public OsFamily apply(final String description) {
-            if (description != null) {
-               if (description.startsWith(CENTOS)) return OsFamily.CENTOS;
-               else if (description.startsWith(DEBIAN)) return OsFamily.DEBIAN;
-               else if (description.startsWith(FEDORA)) return OsFamily.FEDORA;
-               else if (description.startsWith(RHEL)) return OsFamily.RHEL;
-               else if (description.startsWith(UBUNTU)) return OsFamily.UBUNTU;
-               else if (description.startsWith(WINDOWS)) return OsFamily.WINDOWS;
-               else if (description.startsWith(CLOUD_LINUX)) return OsFamily.CLOUD_LINUX;
-            }
-
-            return OsFamily.UNRECOGNIZED;
-         }
-      };
-   }
-
-   /**
-    * Parses the item description to determine the os version
-    *
-    * @return the version or null if the version cannot be determined
-    */
-   public static Function<String, String> osVersion() {
-      return new Function<String, String>() {
-         @Override
-         public String apply(final String description) {
-            OsFamily family = osFamily().apply(description);
-
-            if (Objects.equal(family, OsFamily.CENTOS)) return parseVersion(description, CENTOS);
-            else if (Objects.equal(family, OsFamily.DEBIAN)) return parseVersion(description, DEBIAN);
-            else if (Objects.equal(family, OsFamily.FEDORA)) return parseVersion(description, FEDORA);
-            else if (Objects.equal(family, OsFamily.RHEL)) return parseVersion(description, RHEL);
-            else if (Objects.equal(family, OsFamily.UBUNTU)) return parseVersion(description, UBUNTU);
-            else if (Objects.equal(family, OsFamily.WINDOWS)) return parseVersion(description, WINDOWS);
-            else if (Objects.equal(family, OsFamily.CLOUD_LINUX)) return parseVersion(description, CLOUD_LINUX);
-
-            return null;
-         }
-      };
-   }
-
-   private static String parseVersion(String description, String os) {
-      String noOsName = description.replaceFirst(os, "").trim();
-      return noOsName.split(" ")[0];
-   }
-
-   /**
-    * Parses the item description to determine the number of OS bits
-    * Expects the number to be in parenthesis and to contain the word "bit".
-    * The following return 64: "A (64 bit) OS", "A (64bit) OS"
-    *
-    * @return the number of bits or null if the number of bits cannot be determined
-    */
-   public static Function<String, Integer> osBits() {
-      return new Function<String, Integer>() {
-         @Override
-         public Integer apply(String description) {
-            if (description != null) {
-               Matcher m = OS_BITS_PATTERN.matcher(description);
-               if (m.matches()) {
-                  return Integer.parseInt(m.group(1));
-               }
-            }
-
-            return null;
-         }
-      };
-   }
-
-   /**
-    * Generates an id for an Image.
-    *
-    * @return the generated id
-    */
-   public static Function<ProductItem, String> imageId() {
-      return new Function<ProductItem, String>() {
-         @Override
-         public String apply(ProductItem productItem) {
-            checkNotNull(productItem, "productItem");
-            ProductItemPrice price = ProductItems.price().apply(productItem);
-            return "" + price.getId();
-         }
-      };
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItems.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItems.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItems.java
deleted file mode 100644
index 7c551e1..0000000
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItems.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.compute.functions;
-
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import org.jclouds.softlayer.domain.ProductItem;
-import org.jclouds.softlayer.domain.ProductItemCategory;
-import org.jclouds.softlayer.domain.ProductItemPrice;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
-
-public class ProductItems {
-
-   /**
-    * Creates a function to get the capacity from a product item.
-    */
-   public static Function<ProductItem, Float> capacity() {
-      return new Function<ProductItem, Float>() {
-         @Override
-         public Float apply(ProductItem productItem) {
-            return productItem.getCapacity();
-         }
-      };
-   }
-
-   /**
-    * Creates a function to get the description from a product item.
-    */
-   public static Function<ProductItem, String> description() {
-      return new Function<ProductItem, String>() {
-         @Override
-         public String apply(ProductItem productItem) {
-            return productItem.getDescription();
-         }
-      };
-   }
-
-   /**
-    * Creates a function to get the ProductItemPrice for the ProductItem. Currently returns the
-    * first prices. This will need to be changed if more than one prices is returned.
-    */
-   public static Function<ProductItem, ProductItemPrice> price() {
-      return new Function<ProductItem, ProductItemPrice>() {
-         @Override
-         public ProductItemPrice apply(ProductItem productItem) {
-            if (productItem.getPrices().size() < 1)
-               throw new NoSuchElementException("ProductItem has no prices:" + productItem);
-            return Iterables.get(productItem.getPrices(), 0);
-         }
-      };
-   }
-
-   /**
-    * Creates a function to get the ProductItem for the ProductItemPrice. Copies the category
-    * information from the prices to the item if necessary The ProductItemPrices must have
-    * ProductItems.
-    */
-   public static Function<ProductItemPrice, ProductItem> item() {
-      return new Function<ProductItemPrice, ProductItem>() {
-         @Override
-         public ProductItem apply(ProductItemPrice productItemPrice) {
-            Set<ProductItemCategory> categories = productItemPrice.getCategories();
-            ProductItem item = productItemPrice.getItem();
-            ProductItem.Builder builder = productItemPrice.getItem().toBuilder();
-            if (item.getCategories().size() == 0 && categories.size() != 0) {
-               builder.categories(categories);
-            }
-
-            return builder.build();
-         }
-      };
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardware.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardware.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardware.java
deleted file mode 100644
index f9ddfc7..0000000
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/ProductItemsToHardware.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.compute.functions;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Iterables.filter;
-import static com.google.common.collect.Iterables.get;
-import static com.google.common.collect.Iterables.getOnlyElement;
-import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
-import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCodeMatches;
-import static org.jclouds.softlayer.predicates.ProductItemPredicates.matches;
-
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.HardwareBuilder;
-import org.jclouds.compute.domain.Processor;
-import org.jclouds.compute.domain.Volume;
-import org.jclouds.compute.domain.internal.VolumeImpl;
-import org.jclouds.softlayer.domain.ProductItem;
-import org.jclouds.softlayer.domain.ProductItemPrice;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-/**
- * Converts a set of ProductItems to Hardware. All cores have a speed of 2.0Ghz The Hardware Id will
- * be a comma separated list containing the prices ids: cpus,ram,volume
- */
-@Singleton
-public class ProductItemsToHardware implements Function<Iterable<ProductItem>, Hardware> {
-
-   private static final String GUEST_DISK_CATEGORY_REGEX =  "guest_disk[0-9]";
-   private static final String FIRST_GUEST_DISK = "guest_disk0";
-   private static final String STORAGE_AREA_NETWORK = "SAN";
-
-   private static final String RAM_CATEGORY = "ram";
-
-   private static final String CPU_DESCRIPTION_REGEX = "(Private )?[0-9]+ x ([.0-9]+) GHz Core[s]?";
-   private static final double DEFAULT_CORE_SPEED = 2.0;
-
-   private final Pattern cpuDescriptionRegex;
-   private final Pattern diskCategoryRegex;
-
-   @Inject
-   public ProductItemsToHardware() {
-      this(Pattern.compile(CPU_DESCRIPTION_REGEX), Pattern.compile(GUEST_DISK_CATEGORY_REGEX));
-   }
-
-   public ProductItemsToHardware(Pattern cpuDescriptionRegex, Pattern diskCategoryRegex) {
-      this.cpuDescriptionRegex = checkNotNull(cpuDescriptionRegex, "cpuDescriptionRegex");
-      this.diskCategoryRegex = checkNotNull(diskCategoryRegex, "diskCategoryRegex");
-   }
-
-   @Override
-   public Hardware apply(Iterable<ProductItem> items) {
-
-      ProductItem coresItem = getOnlyElement(filter(items, matches(cpuDescriptionRegex)));
-      ProductItem ramItem = getOnlyElement(filter(items, categoryCode(RAM_CATEGORY)));
-      ProductItem volumeItem = get(filter(items, categoryCode(FIRST_GUEST_DISK)), 0);
-
-      String hardwareId = hardwareId().apply(ImmutableList.of(coresItem, ramItem, volumeItem));
-      double cores = ProductItems.capacity().apply(coresItem).doubleValue();
-      Matcher cpuMatcher = cpuDescriptionRegex.matcher(coresItem.getDescription());
-      double coreSpeed = (cpuMatcher.matches()) ? Double.parseDouble(cpuMatcher.group(cpuMatcher.groupCount())) : DEFAULT_CORE_SPEED;
-      int ram = ProductItems.capacity().apply(ramItem).intValue() * 1024;
-
-      return new HardwareBuilder().ids(hardwareId).processors(ImmutableList.of(new Processor(cores, coreSpeed)))
-               .ram(ram).hypervisor("XenServer")
-               .volumes(
-                  Iterables.transform(filter(items, categoryCodeMatches(diskCategoryRegex)),
-                        new Function<ProductItem, Volume>() {
-                           @Override
-                           public Volume apply(ProductItem item) {
-                              float volumeSize = ProductItems.capacity().apply(item);
-                              return new VolumeImpl(
-                                       item.getId() + "",
-                                       item.getDescription().indexOf(STORAGE_AREA_NETWORK) != -1 ? Volume.Type.SAN : Volume.Type.LOCAL,
-                                       volumeSize, null, categoryCode(FIRST_GUEST_DISK).apply(item), false);
-                           }
-                        })).build();
-   }
-
-   /**
-    * Generates a hardwareId based on the priceId's of the items in the list
-    *
-    * @return comma separated list of priceid's
-    */
-   public static Function<List<ProductItem>, String> hardwareId() {
-      return new Function<List<ProductItem>, String>() {
-         @Override
-         public String apply(List<ProductItem> productItems) {
-            StringBuilder builder = new StringBuilder();
-            for (ProductItem item : productItems) {
-               ProductItemPrice price = ProductItems.price().apply(item);
-               builder.append(price.getId()).append(",");
-            }
-            return builder.toString().substring(0, builder.lastIndexOf(","));
-         }
-      };
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToHardware.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToHardware.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToHardware.java
new file mode 100644
index 0000000..d6c6367
--- /dev/null
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToHardware.java
@@ -0,0 +1,65 @@
+/*
+ * 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.compute.functions;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.internal.VolumeImpl;
+import org.jclouds.softlayer.domain.VirtualGuest;
+import org.jclouds.softlayer.domain.VirtualGuestBlockDevice;
+
+import javax.inject.Singleton;
+
+@Singleton
+public class VirtualGuestToHardware implements Function<VirtualGuest, Hardware> {
+
+   @Override
+   public Hardware apply(final VirtualGuest from) {
+      HardwareBuilder builder = new HardwareBuilder().ids(from.getId() + "")
+              .name(from.getHostname())
+              .hypervisor("XenServer")
+              .processors(ImmutableList.of(new Processor(from.getStartCpus(), 2)))
+              .ram(from.getMaxMemory());
+
+      if (from.getVirtualGuestBlockDevices() != null) {
+         builder.volumes(
+                 FluentIterable.from(from.getVirtualGuestBlockDevices()).filter(new Predicate<VirtualGuestBlockDevice>() {
+                    @Override
+                    public boolean apply(VirtualGuestBlockDevice input) {
+                       return input.getMountType().equals("Disk");
+                    }
+                 })
+                         .transform(new Function<VirtualGuestBlockDevice, Volume>() {
+                            @Override
+                            public Volume apply(VirtualGuestBlockDevice item) {
+                               float volumeSize = item.getVirtualDiskImage().getCapacity();
+                               return new VolumeImpl(
+                                       item.getId() + "",
+                                       from.isLocalDiskFlag() ? Volume.Type.LOCAL : Volume.Type.SAN,
+                                       volumeSize, null, item.getBootableFlag() == 1, false);
+                            }
+                         }).toSet());
+      }
+      return builder.build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToImage.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToImage.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToImage.java
new file mode 100644
index 0000000..6c70347
--- /dev/null
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToImage.java
@@ -0,0 +1,68 @@
+/*
+ * 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.compute.functions;
+
+import com.google.common.base.Function;
+import com.google.inject.Inject;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.logging.Logger;
+import org.jclouds.softlayer.domain.VirtualGuest;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+@Singleton
+public class VirtualGuestToImage implements Function<VirtualGuest, Image> {
+
+   private static final String UNRECOGNIZED = "UNRECOGNIZED";
+
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+
+   private final OperatingSystemToImage operatingSystemToImage;
+
+   @Inject
+   protected VirtualGuestToImage(OperatingSystemToImage operatingSystemToImage) {
+      this.operatingSystemToImage = checkNotNull(operatingSystemToImage, "operatingSystemToImage");
+   }
+
+   @Override
+   public Image apply(VirtualGuest from) {
+      checkNotNull(from, "from");
+      if (from.getOperatingSystem() == null) {
+         return new ImageBuilder().ids(from.getId() + "")
+                 .name(from.getHostname())
+                 .status(Image.Status.UNRECOGNIZED)
+                 .operatingSystem(OperatingSystem.builder()
+                         .family(OsFamily.UNRECOGNIZED)
+                         .version(UNRECOGNIZED)
+                         .description(UNRECOGNIZED)
+                         .build())
+                 .build();
+      } else {
+         return operatingSystemToImage.apply(from.getOperatingSystem());
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/717a545b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToNodeMetadata.java
----------------------------------------------------------------------
diff --git a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToNodeMetadata.java b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToNodeMetadata.java
index 6267110..45c28cd 100644
--- a/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToNodeMetadata.java
+++ b/providers/softlayer/src/main/java/org/jclouds/softlayer/compute/functions/VirtualGuestToNodeMetadata.java
@@ -18,38 +18,29 @@ package org.jclouds.softlayer.compute.functions;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.collect.FluentIterable.from;
-
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import javax.annotation.Resource;
 import javax.inject.Inject;
-import javax.inject.Named;
 import javax.inject.Singleton;
 
 import org.jclouds.collect.Memoized;
-import org.jclouds.compute.domain.Hardware;
 import org.jclouds.compute.domain.Image;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.NodeMetadata.Status;
 import org.jclouds.compute.domain.NodeMetadataBuilder;
 import org.jclouds.compute.functions.GroupNamingConvention;
-import org.jclouds.compute.reference.ComputeServiceConstants;
 import org.jclouds.domain.Location;
 import org.jclouds.location.predicates.LocationPredicates;
-import org.jclouds.logging.Logger;
-import org.jclouds.softlayer.SoftLayerApi;
-import org.jclouds.softlayer.domain.ProductItem;
-import org.jclouds.softlayer.domain.ProductOrder;
+import org.jclouds.softlayer.domain.TagReference;
 import org.jclouds.softlayer.domain.VirtualGuest;
-import org.jclouds.softlayer.exceptions.SoftLayerOrderItemDuplicateException;
-import org.jclouds.softlayer.predicates.ProductItemPredicates;
 
 import com.google.common.base.Function;
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
 
 @Singleton
 public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMetadata> {
@@ -60,107 +51,54 @@ public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMe
          .put(VirtualGuest.State.UNRECOGNIZED, Status.UNRECOGNIZED).build();
 
    private final Supplier<Set<? extends Location>> locations;
-   private final GetHardwareForVirtualGuest hardware;
-   private final GetImageForVirtualGuest images;
    private final GroupNamingConvention nodeNamingConvention;
+   private final VirtualGuestToImage virtualGuestToImage;
+   private final VirtualGuestToHardware virtualGuestToHardware;
 
    @Inject
    VirtualGuestToNodeMetadata(@Memoized Supplier<Set<? extends Location>> locations,
-         GetHardwareForVirtualGuest hardware, GetImageForVirtualGuest images,
-         GroupNamingConvention.Factory namingConvention) {
+         GroupNamingConvention.Factory namingConvention, VirtualGuestToImage virtualGuestToImage,
+         VirtualGuestToHardware virtualGuestToHardware) {
       this.nodeNamingConvention = checkNotNull(namingConvention, "namingConvention").createWithoutPrefix();
       this.locations = checkNotNull(locations, "locations");
-      this.hardware = checkNotNull(hardware, "hardware");
-      this.images = checkNotNull(images, "images");
+      this.virtualGuestToImage = checkNotNull(virtualGuestToImage, "virtualGuestToImage");
+      this.virtualGuestToHardware = checkNotNull(virtualGuestToHardware, "virtualGuestToHardware");
    }
 
    @Override
    public NodeMetadata apply(VirtualGuest from) {
-      // convert the result object to a jclouds NodeMetadata
       NodeMetadataBuilder builder = new NodeMetadataBuilder();
       builder.ids(from.getId() + "");
       builder.name(from.getHostname());
-      builder.hostname(from.getHostname());
-      if (from.getDatacenter() != null)
+      builder.hostname(from.getHostname() + from.getDomain());
+      if (from.getDatacenter() != null) {
          builder.location(from(locations.get()).firstMatch(
-               LocationPredicates.idEquals(from.getDatacenter().getId() + "")).orNull());
+                 LocationPredicates.idEquals(from.getDatacenter().getId() + "")).orNull());
+      }
       builder.group(nodeNamingConvention.groupInUniqueNameOrNull(from.getHostname()));
-
-      Image image = images.getImage(from);
+      builder.hardware(virtualGuestToHardware.apply(from));
+      Image image = virtualGuestToImage.apply(from);
       if (image != null) {
          builder.imageId(image.getId());
          builder.operatingSystem(image.getOperatingSystem());
       }
-
-      builder.hardware(hardware.getHardware(from));
-
-      builder.status(serverStateToNodeStatus.get(from.getPowerState().getKeyName()));
-
-      // These are null for 'bad' guest orders in the HALTED state.
+      if (from.getPowerState() != null) {
+         builder.status(serverStateToNodeStatus.get(from.getPowerState().getKeyName()));
+      }
       if (from.getPrimaryIpAddress() != null)
-         builder.publicAddresses(ImmutableSet.<String> of(from.getPrimaryIpAddress()));
+         builder.publicAddresses(ImmutableSet.of(from.getPrimaryIpAddress()));
       if (from.getPrimaryBackendIpAddress() != null)
-         builder.privateAddresses(ImmutableSet.<String> of(from.getPrimaryBackendIpAddress()));
-      return builder.build();
-   }
-
-   @Singleton
-   public static class GetHardwareForVirtualGuest {
-
-      private final SoftLayerApi api;
-      private final Function<Iterable<ProductItem>, Hardware> productItemsToHardware;
-
-      @Inject
-      public GetHardwareForVirtualGuest(SoftLayerApi api,
-            Function<Iterable<ProductItem>, Hardware> productItemsToHardware) {
-         this.api = checkNotNull(api, "api");
-         this.productItemsToHardware = checkNotNull(productItemsToHardware, "productItemsToHardware");
-
-      }
-
-      public Hardware getHardware(VirtualGuest guest) {
-         // 'bad' orders have no start cpu's and cause the order lookup to fail.
-         if (guest.getStartCpus() < 1)
-            return null;
-         ProductOrder order = api.getVirtualGuestApi().getOrderTemplate(guest.getId());
-         if (order == null)
-            return null;
-         Iterable<ProductItem> items = Iterables.transform(order.getPrices(), ProductItems.item());
-         return productItemsToHardware.apply(items);
-      }
-   }
-
-   @Singleton
-   public static class GetImageForVirtualGuest {
-
-      @Resource
-      @Named(ComputeServiceConstants.COMPUTE_LOGGER)
-      protected Logger logger = Logger.NULL;
-
-      private SoftLayerApi api;
-
-      @Inject
-      public GetImageForVirtualGuest(SoftLayerApi api) {
-         this.api = api;
-      }
-
-      public Image getImage(VirtualGuest guest) {
-         ProductOrder order = null;
-         // 'bad' orders have no start cpu's and cause the order lookup to fail.
-         if (guest.getStartCpus() < 1)
-            return null;
-         try {
-            order = api.getVirtualGuestApi().getOrderTemplate(guest.getId());
-         } catch (SoftLayerOrderItemDuplicateException e) {
-            // this is a workaround because SoftLayer throws sometimes 500 internal server errors for the above method call
-            logger.warn(e, "Cannot get order template for virtualGuestId(%s)", guest.getId());
+         builder.privateAddresses(ImmutableSet.of(from.getPrimaryBackendIpAddress()));
+      if (from.getTagReferences() != null && !from.getTagReferences().isEmpty()) {
+         List<String> tags = Lists.newArrayList();
+         for (TagReference tagReference : from.getTagReferences()) {
+            if (tagReference != null) {
+               tags.add(tagReference.getTag().getName());
+            }
          }
-         if (order == null)
-            return null;
-         Iterable<ProductItem> items = Iterables.transform(order.getPrices(), ProductItems.item());
-         ProductItem os = Iterables.find(items, ProductItemPredicates.categoryCode("os"));
-         return new ProductItemToImage().apply(os);
+         builder.tags(tags);
       }
+      return builder.build();
    }
 
 }