nacx requested changes on this pull request.

Thanks @alibazlamit!
I've finally had time to review this properly. There are several comments, and 
some structural ones such as using the DataCenter as the entity to represent a 
Location. If we do that (I don't see why we shouldn't), we should also remove 
the location properties from the metadata.

> @@ -49,12 +53,23 @@ public OneAndOneProviderMetadata(Builder builder) {
 
    public static Properties defaultProperties() {
       Properties properties = OneAndOneApiMetadata.defaultProperties();
+
+      properties.setProperty(PROPERTY_REGIONS, "de,us,es,gb");
+      properties.setProperty(PROPERTY_REGION + ".de." + ISO3166_CODES, 
"DE-DEU");
+      properties.setProperty(PROPERTY_REGION + ".us." + ISO3166_CODES, 
"US-USA");
+      properties.setProperty(PROPERTY_REGION + ".es." + ISO3166_CODES, 
"ES-ESP");
+      properties.setProperty(PROPERTY_REGION + ".gb." + ISO3166_CODES, 
"GB-GBR");

We usually put here the ISO_3166-2 does, such as ES-CT, etc.

> +import org.jclouds.compute.ComputeServiceAdapter;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.util.ComputeServiceUtils;
+import static 
org.jclouds.compute.util.ComputeServiceUtils.getPortRangesFromList;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.logging.Logger;
+import org.jclouds.rest.ResourceNotFoundException;
+
+@Singleton
+public class OneandoneComputeServiceAdapter implements 
ComputeServiceAdapter<Server, HardwareFlavour, SingleServerAppliance, Location> 
{

Why don't we use here the Datacenter object instead of a Location? That way we 
could return the datacenter id as the location id, and we could implement the 
list locations here based on the list of existing data centers.

> +                 = 
> org.apache.jclouds.oneandone.rest.domain.Hardware.CreateHardware.create(cores,
>  1, ram, hdds);
+         final Server.CreateServer serverRequest = 
Server.CreateServer.builder()
+                 .name(name)
+                 .description(name)
+                 .hardware(hardwareRequest)
+                 .rsaKey(options.getPublicKey())
+                 .password(privateKey == null ? password : null)
+                 .applianceId(image.getId())
+                 .dataCenterId(dataCenterId)
+                 .powerOn(Boolean.TRUE).build();
+
+         logger.trace("<< provisioning server '%s'", serverRequest);
+
+         server = api.serverApi().create(serverRequest);
+
+         waitServerUntilAvailable.apply(server);

I assume this is required in order to create the firewall rules below? Can we 
apply them even if the server is not yet available?

> +                    .portTo(range.getValue())
+                    .protocol(Types.RuleProtocol.TCP)
+                    .build();
+            rules.add(rule);
+         }
+         if (inboundPorts.length > 0) {
+            FirewallPolicy rule = 
api.firewallPolicyApi().create(FirewallPolicy.CreateFirewallPolicy.create(server.name()
 + " firewall policy", "desc", rules));
+            api.serverApi().addFirewallPolicy(updateServer.id(), 
updateServer.ips().get(0).id(), rule.id());
+            waitServerUntilAvailable.apply(server);
+         }
+
+         logger.trace(">> provisioning complete for server. returned id='%s'", 
server.id());
+
+      } catch (Exception ex) {
+         logger.error(ex, ">> failed to provision server. rollbacking..");
+         throw Throwables.propagate(ex);

We should do better here and rollback the created server (if the firewall 
creation failed) and any created firewall rule.

> +              .password(password)
+              .privateKey(privateKey)
+              .build();
+
+      return new NodeAndInitialCredentials<Server>(updateServer, 
updateServer.id(), serverCredentials);
+   }
+
+   @Override
+   public List<HardwareFlavour> listHardwareProfiles() {
+      return api.serverApi().listHardwareFlavours();
+   }
+
+   @Override
+   public Iterable<SingleServerAppliance> listImages() {
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, Types.OSImageType.Minimal.toString(), null);

Why only Minimal?

> +   }
+
+   @Override
+   public Iterable<SingleServerAppliance> listImages() {
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, Types.OSImageType.Minimal.toString(), null);
+      List<ServerAppliance> list = api.serverApplianceApi().list(options);
+      List<SingleServerAppliance> results = new 
ArrayList<SingleServerAppliance>();
+      for (ServerAppliance appliance : list) {
+         List<SingleServerAppliance.AvailableDataCenters> availableDatacenters 
= new ArrayList<SingleServerAppliance.AvailableDataCenters>();
+         for (String dcId : appliance.availableDataCenters()) {
+            
availableDatacenters.add(SingleServerAppliance.AvailableDataCenters.create(dcId,
 ""));
+         }
+         results.add(SingleServerAppliance.create(appliance.id(), 
appliance.name(), availableDatacenters, appliance.osInstallationBase(),
+                 appliance.osFamily(), appliance.os(), appliance.osVersion(), 
appliance.osArchitecture(), appliance.osImageType(), appliance.minHddSize(),
+                 appliance.type(), appliance.state(), appliance.version(), 
appliance.categories(), appliance.eulaUrl()));

Consider adding an auto value Builder for objects with such a number of 
constructor args.

> +   static class ServerRunningPredicate implements Predicate<Server> {
+
+      private final OneAndOneApi api;
+      private final Types.ServerState expectedState;
+
+      public ServerRunningPredicate(OneAndOneApi api, Types.ServerState 
expectedState) {
+         this.api = checkNotNull(api, "api must not be null");
+         this.expectedState = checkNotNull(expectedState, "expectedState must 
not be null");
+      }
+
+      @Override
+      public boolean apply(Server serverRef) {
+
+         checkNotNull(serverRef, "serverRef");
+         //give time for the operation to actually start
+         Uninterruptibles.sleepUninterruptibly(10, TimeUnit.SECONDS);

We need to get rid of this. This predicate will probably be used in a 
`Predicates2.retry`, so we shouldn't be waiting 10 seconds every time this 
predicate is evaluated. This needs to be removed.

> +      this.fnVolume = fnVolume;
+      this.fnHardware = fnHardware;
+      this.groupNamingConvention = groupNamingConvention.createWithoutPrefix();
+   }
+
+   @Override
+   public NodeMetadata apply(final Server server) {
+      checkNotNull(server, "Null server");
+
+      DataCenter dataCenter = 
api.dataCenterApi().get(server.datacenter().id());
+      Location location = find(locations.get(), 
idEquals(dataCenter.countryCode().toLowerCase()));
+      Hardware hardware = null;
+      //check if the server was built on a hardware flavour(Fixed instance)
+      if (server.hardware().fixedInstanceSizeId() != null && 
!"0".equals(server.hardware().fixedInstanceSizeId())) {
+         HardwareFlavour flavour = 
api.serverApi().getHardwareFlavour(server.hardware().fixedInstanceSizeId());
+         hardware = fnHardware.apply(flavour);

Instead of doing this, you can have the `Supplier<Map<String, ? extends 
Hardware>>` injected in this class (which is the cached list of existing 
hardwares, indexed by id) and just get by id on the map. This will save a call 
to the API for each node.

> +         }
+
+         List<Processor> processors = new ArrayList<Processor>();
+         for (int i = 0; i < server.hardware().vcore(); i++) {
+            Processor proc = new 
Processor(server.hardware().coresPerProcessor(), 1d);
+            processors.add(proc);
+         }
+         AutomaticHardwareIdSpec id = 
AutomaticHardwareIdSpec.automaticHardwareIdSpecBuilder(server.hardware().vcore(),
 (int) minRam, Optional.of((float) size));
+         hardware = new HardwareBuilder()
+                 .ids(id.toString())
+                 .ram((int) minRam)
+                 .processors(ImmutableList.copyOf(processors))
+                 .hypervisor("kvm")
+                 .volumes(volumes)
+                 .location(location)
+                 .build();

Worth making 
[this](https://github.com/jclouds/jclouds/blob/master/compute/src/main/java/org/jclouds/compute/domain/internal/ArbitraryCpuRamTemplateBuilderImpl.java#L50)
 publicly visible so you can call it here instead of manually building the 
hardware. This will keep the provider working with future changes we make 
there. Perhaps that logic could be moved to a `hardwareFromId` method in the 
spec.

> +               
> availableDatacenters.add(SingleServerAppliance.AvailableDataCenters.create(dcId,
>  ""));
+            }
+            image = SingleServerAppliance.create(appliance.id(), 
appliance.name(), availableDatacenters, appliance.osInstallationBase(),
+                    appliance.osFamily(), appliance.os(), 
appliance.osVersion(), appliance.osArchitecture(), appliance.osImageType(), 
appliance.minHddSize(),
+                    appliance.type(), appliance.state(), appliance.version(), 
appliance.categories(), appliance.eulaUrl());
+         }
+      } catch (Exception ex) {
+         throw new ResourceNotFoundException("No image with id '" + 
appliance.id() + "' was found");
+      }
+      OsFamily osFamily = 
SingleServerApplianceToImage.parseOsFamily(image.osVersion());
+      OperatingSystem os = OperatingSystem.builder()
+              .description(image.name())
+              .family(osFamily)
+              .version(SingleServerApplianceToImage.parseVersion(image.os()))
+              
.is64Bit(SingleServerApplianceToImage.is64Bit(image.osArchitecture()))
+              .build();

There should be no need to manually get the images here. You can also inject 
the `Supplier<Map<String, ? extends Image>>`, and get the image by id from the 
image cache, saving one api call per node.

> +            return OsFamily.UBUNTU;
+         }
+
+         if (osFamily.toLowerCase().contains("debian")) {
+            return OsFamily.DEBIAN;
+         }
+
+         if (osFamily.toLowerCase().contains("centos")) {
+            return OsFamily.CENTOS;
+         }
+
+         if (osFamily.toLowerCase().contains("ArchLinux")) {
+            return OsFamily.ARCH;
+         }
+      }
+      return OsFamily.UNRECOGNIZED;

Can we change this to use a similar approach?

> +
+      logger.info(">> looking for a datacenter in %s", 
template.getLocation().getId());
+
+      // Try to find an existing datacenter in the selected location
+      DataCenter dataCenter = find(api.dataCenterApi().list(), new 
Predicate<DataCenter>() {
+         @Override
+         public boolean apply(DataCenter input) {
+            // The location field is not populated when getting the list of 
datacenters
+            DataCenter details = api.dataCenterApi().get(input.id());
+            return details != null && 
template.getLocation().getId().equals(details.countryCode().toLowerCase());
+         }
+      });
+
+      return super.execute(group, count, new TemplateWithDataCenter(template, 
dataCenter), goodNodes, badNodes,
+              customizationResponses);
+   }

If we already use the DataCenter object as the location object in the adapter, 
we shouldn't need this class, as this list would be performed in the list 
locations method.

> +              nodeTerminated, nodeSuspended, initScriptRunnerFactory, 
> initAdminAccess, runScriptOnNodeFactory,
+              persistNodeCredentials, timeouts, userExecutor, imageExtension, 
securityGroupExtension);
+      this.cleanupResources = cleanupResources;
+   }
+
+   @Override
+   protected void cleanUpIncidentalResourcesOfDeadNodes(Set<? extends 
NodeMetadata> deadNodes) {
+      for (NodeMetadata deadNode : deadNodes) {
+         try {
+            cleanupResources.cleanupNode(deadNode.getId());
+         } catch (Exception ex) {
+            logger.warn(ex, "Error cleaning up resources for node %s", 
deadNode);
+         }
+      }
+   }
+}

The compute service delete node already calls here, so this class shouldn't be 
necessary.

> +      if (delegate == null) {
+         if (other.delegate != null) {
+            return false;
+         }
+      } else if (!delegate.equals(other.delegate)) {
+         return false;
+      }
+      return true;
+   }
+
+   @Override
+   public String toString() {
+      return delegate.toString();
+   }
+
+}

We shouldn't need this if we go for the DataCenter as Location approach.

>     public static final String POLL_PREDICATE_PRIVATE_NETWORK = 
> "jclouds.oneandone.rest.predicate.privatenetwork";
-   public static final String AUTH_TOKEN = "oneandone.identity";
+   public static final String AUTH_TOKEN = "oneandone.crednetial";

Remove this property and the line that uses it in the live test base class. 
jclouds already sets it to the right value 
[here](https://github.com/jclouds/jclouds/blob/master/core/src/test/java/org/jclouds/apis/BaseApiLiveTest.java#L60).

> +
+   public String getDescription() {
+      return description;
+   }
+
+   public static Location fromValue(String v) {
+      return Location.fromId(v);
+   }
+
+   public static Location fromId(String id) {
+      for (Location location : values()) {
+         if (location.id.equals(id)) {
+            return location;
+         }
+      }
+      throw new IllegalArgumentException();

Add a message to the exception.

> +   public abstract String state();
+
+   @Nullable
+   public abstract String version();
+
+   @Nullable
+   public abstract List<String> categories();
+
+   @Nullable
+   public abstract String eulaUrl();
+
+   @SerializedNames({"id", "name", "available_datacenters", 
"os_installation_base", "os_family", "os", "os_version", "os_architecture", 
"os_image_type",
+      "min_hdd_size", "type", "state", "version", "categories", "eula_url"})
+   public static ServerAppliance create(String id, String name, List<String> 
availableDataCenters, String osInstallationBase, Types.OSFamliyType osFamily, 
String os,
+           String osVersion, int osArchitecture, Types.OSImageType 
osImageType, int minHddSize, ApplianceType type, String state, String version, 
List<String> categories, String eulaUrl) {
+      return new AutoValue_ServerAppliance(id, name, availableDataCenters == 
null ? ImmutableList.<String>of() : availableDataCenters, osInstallationBase, 
osFamily, os, osVersion, osArchitecture, osImageType, minHddSize, type, state, 
version, categories == null ? ImmutableList.<String>of() : categories, eulaUrl);

Use `ImmutableList.copyOf` when lists are not null.

> +   public abstract String state();
+
+   @Nullable
+   public abstract String version();
+
+   @Nullable
+   public abstract List<String> categories();
+
+   @Nullable
+   public abstract String eulaUrl();
+
+   @SerializedNames({"id", "name", "available_datacenters", 
"os_installation_base", "os_family", "os", "os_version", "os_architecture", 
"os_image_type",
+      "min_hdd_size", "type", "state", "version", "categories", "eula_url"})
+   public static SingleServerAppliance create(String id, String name, 
List<AvailableDataCenters> availableDataCenters, String osInstallationBase, 
Types.OSFamliyType osFamily, String os,
+           String osVersion, int osArchitecture, Types.OSImageType 
osImageType, int minHddSize, Types.ApplianceType type, String state, String 
version, List<String> categories, String eulaUrl) {
+      return new AutoValue_SingleServerAppliance(id, name, 
availableDataCenters == null ? ImmutableList.<AvailableDataCenters>of() : 
availableDataCenters, osInstallationBase, osFamily, os, osVersion, 
osArchitecture, osImageType, minHddSize, type, state, version, categories == 
null ? ImmutableList.<String>of() : categories, eulaUrl);

Use `ImmutableList.copyOf` when lists are not null.

> +import com.google.inject.Inject;
+import javax.annotation.Resource;
+import javax.inject.Named;
+import static org.jclouds.Constants.PROPERTY_MAX_RATE_LIMIT_WAIT;
+import static org.jclouds.Constants.PROPERTY_MAX_RETRIES;
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.HttpRetryHandler;
+import org.jclouds.logging.Logger;
+
+/**
+ * Retry handler that takes into account the provider rate limit and delays the
+ * requests until they are known to succeed.
+ */
+@Beta
+public abstract class AliRateLimitRetryHandler implements HttpRetryHandler {

Remove it :)

> +import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.jclouds.oneandone.rest.domain.SingleServerAppliance;
+import 
org.apache.jclouds.oneandone.rest.domain.SingleServerAppliance.AvailableDataCenters;
+import org.apache.jclouds.oneandone.rest.domain.Types;
+
+public class ServerApplianceAdapter extends TypeAdapter {
+
+   private com.google.gson.reflect.TypeToken adapterclass;
+   private Gson gson;
+
+   public ServerApplianceAdapter(com.google.gson.reflect.TypeToken 
adapterclass) {
+      this.adapterclass = adapterclass;
+      gson = new Gson();

Can we get the jclouds `Json` instance injected here instead?

> +      // OneAndOne doesn't support tags
+   }
+
+   @Override
+   protected void checkUserMetadataContains(NodeMetadata node, 
ImmutableMap<String, String> userMetadata) {
+      // OneAndOne doesn't support user metadata
+   }
+
+   @Override
+   protected void checkResponseEqualsHostname(ExecResponse execResponse, 
NodeMetadata node1) {
+      // OneAndOne doesn't support hostname
+   }
+
+   @Override
+   protected void checkOsMatchesTemplate(NodeMetadata node) {
+      // Not enough description from API to match template

If we change the node transformation function to use the hardware and image 
caches, we should be able to have this check work. We should definitely not 
override this.

> +import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.jclouds.oneandone.rest.domain.Hardware;
+import org.apache.jclouds.oneandone.rest.domain.Hdd;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneApiMockTest;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.VolumeBuilder;
+import org.jclouds.compute.util.AutomaticHardwareIdSpec;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "CustomHardwareToHardwareTest", 
singleThreaded = true)
+public class CustomHardwareToHardwareTest extends BaseOneAndOneApiMockTest {

Do we really need to extend this class? That one should be for mock api tests.

> +import com.squareup.okhttp.mockwebserver.MockResponse;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.jclouds.oneandone.rest.domain.HardwareFlavour;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneApiMockTest;
+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.VolumeBuilder;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "HardwareFlavourToHardwareTest", 
singleThreaded = true)
+public class HardwareFlavourToHardwareTest extends BaseOneAndOneApiMockTest {

Same comment about inheritance.

> + * 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.apache.jclouds.oneandone.rest.compute.function;
+
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneApiMockTest;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.VolumeBuilder;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "HddToVolumeTest", singleThreaded = true)
+public class HddToVolumeTest extends BaseOneAndOneApiMockTest {

Same inheritance comment.

> +
+   private HardwareFlavourToHardware fnHardware;
+
+   @BeforeTest
+   public void setup() {
+      this.fnHardware = new HardwareFlavourToHardware();
+   }
+
+   @Test
+   public void testHardwareFlavourToHardware() {
+
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/compute/hardware.json"))
+      );
+
+      org.apache.jclouds.oneandone.rest.domain.HardwareFlavour hardware = 
api.serverApi().getHardwareFlavour("some-id");

There is no need to mock api calls to implement this test.

> +
+   private HddToVolume fnVolume;
+
+   @BeforeTest
+   public void setup() {
+      this.fnVolume = new HddToVolume();
+   }
+
+   @Test
+   public void testHddToVolume() {
+
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/compute/volume.json"))
+      );
+
+      org.apache.jclouds.oneandone.rest.domain.Hdd hdd = 
api.serverApi().getHdd("some-id", "hdd-id");

There is no need to mock api calls to implement this test.

> +import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.VolumeBuilder;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "ServerToNodeMetadataTest", singleThreaded = 
true)
+public class ServerToNodeMetadataTest extends BaseOneAndOneApiMockTest {

Same about inheritance.

> +      expect(api.dataCenterApi()).andReturn(dataCenterApi);
+      expect(api.serverApi()).andReturn(serverApi);
+      expect(api.serverApplianceApi()).andReturn(serverApplianceApi);
+
+      replay(serverApplianceApi, dataCenterApi, serverApi, api);
+
+      this.fnNodeMetadata = new ServerToNodeMetadata(new HddToVolume(), new 
HardwareFlavourToHardware(), locationsSupply, api, namingConvention);
+   }
+
+   @Test
+   public void testServerToNodeMetadata() {
+
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/compute/server.json"))
+      );
+      Server serverObject = api.serverApi().get("mock");

There is no need to mock api calls to implement this test.

> + */
+package org.apache.jclouds.oneandone.rest.compute.function;
+
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import org.apache.jclouds.oneandone.rest.domain.SingleServerAppliance;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneApiMockTest;
+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 static org.testng.Assert.assertEquals;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "ServerApplianceToImageTest", singleThreaded 
= true)
+public class SingleServerApplianceToImageTest extends BaseOneAndOneApiMockTest 
{

Same inheritance comment.

> +
+   private SingleServerApplianceToImage fnImage;
+
+   @BeforeTest
+   public void setup() {
+      this.fnImage = new SingleServerApplianceToImage();
+   }
+
+   @Test
+   public void testImageToImage() {
+
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/compute/image.json"))
+      );
+
+      SingleServerAppliance image = api.serverApplianceApi().get("some-id");

There is no need to mock api calls to implement this test.

> +@Test(groups = "live", testName = "DataCenterApiLiveTest")
+public class DataCenterApiLiveTest extends BaseOneAndOneLiveTest {
+
+   private DataCenter currentDataCenter;
+   private List<DataCenter> dataCenters;
+
+   private DataCenterApi dataCenterApi() {
+
+      return api.dataCenterApi();
+   }
+
+   @Test
+   public void testList() {
+      dataCenters = dataCenterApi().list();
+      currentDataCenter = dataCenters.get(0);
+      assertNotNull(dataCenters);

Check this before calling get.

> +@Test(groups = "live", testName = "ServerApplianceApiLiveTest")
+public class ServerApplianceApiLiveTest extends BaseOneAndOneLiveTest {
+
+   private ServerAppliance currentAppliance;
+   private List<ServerAppliance> appliances;
+
+   private ServerApplianceApi serverApplianceApi() {
+
+      return api.serverApplianceApi();
+   }
+
+   @Test
+   public void testList() {
+      appliances = serverApplianceApi().list();
+      currentAppliance = appliances.get(0);
+      Assert.assertTrue(appliances.size() > 0);

Assert this before calling get.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/jclouds/jclouds-labs/pull/338#pullrequestreview-22002212

Reply via email to