Repository: jclouds-labs
Updated Branches:
  refs/heads/master 4d80bd7a5 -> eeaa3c668


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/DataCenterApi.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/DataCenterApi.java
 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/DataCenterApi.java
new file mode 100644
index 0000000..0a9318c
--- /dev/null
+++ 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/DataCenterApi.java
@@ -0,0 +1,55 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.features;
+
+import java.io.Closeable;
+import java.util.List;
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.jclouds.oneandone.rest.domain.DataCenter;
+import org.apache.jclouds.oneandone.rest.domain.options.GenericQueryOptions;
+import org.apache.jclouds.oneandone.rest.filters.AuthenticateRequest;
+import org.jclouds.Fallbacks;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+
+@Path("/datacenters")
+@Produces("application/json")
+@Consumes("application/json")
+@RequestFilters(AuthenticateRequest.class)
+public interface DataCenterApi extends Closeable {
+
+   @Named("datacenter:list")
+   @GET
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<DataCenter> list();
+
+   @Named("datacenter:list")
+   @GET
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<DataCenter> list(GenericQueryOptions options);
+
+   @Named("datacenter:get")
+   @GET
+   @Path("/{dataCenterId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   DataCenter get(@PathParam("dataCenterId") String dataCenterId);
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApi.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApi.java
 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApi.java
new file mode 100644
index 0000000..cfb0ea0
--- /dev/null
+++ 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApi.java
@@ -0,0 +1,91 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.features;
+
+import com.google.inject.Inject;
+import com.google.inject.TypeLiteral;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+import java.util.List;
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import org.apache.jclouds.oneandone.rest.domain.ServerAppliance;
+import org.apache.jclouds.oneandone.rest.domain.SingleServerAppliance;
+import org.apache.jclouds.oneandone.rest.domain.options.GenericQueryOptions;
+import org.apache.jclouds.oneandone.rest.filters.AuthenticateRequest;
+import org.apache.jclouds.oneandone.rest.util.ServerApplianceParser;
+import org.jclouds.Fallbacks;
+import org.jclouds.http.functions.ParseJson;
+import org.jclouds.json.Json;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.util.Strings2;
+
+@Path("/server_appliances")
+@Consumes("application/json")
+@RequestFilters(AuthenticateRequest.class)
+public interface ServerApplianceApi extends Closeable {
+
+   @Named("serverappliance:list")
+   @GET
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<ServerAppliance> list();
+
+   @Named("serverappliance:list")
+   @GET
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<ServerAppliance> list(GenericQueryOptions options);
+
+   @Named("serverappliance:get")
+   @GET
+   @Path("/{serverApplianceId}")
+   @ResponseParser(ServerApplianceApi.SingleServerApplianceParser.class)
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   SingleServerAppliance get(@PathParam("serverApplianceId") String 
serverApplianceId);
+
+   static final class SingleServerApplianceParser extends 
ParseJson<SingleServerAppliance> {
+
+      static final TypeLiteral<SingleServerAppliance> single = new 
TypeLiteral<SingleServerAppliance>() {
+      };
+      final ServerApplianceParser parseService;
+
+      @Inject
+      SingleServerApplianceParser(Json json, ServerApplianceParser parseId) {
+         super(json, single);
+         this.parseService = parseId;
+      }
+
+      @SuppressWarnings("unchecked")
+      @Override
+      public <V> V apply(InputStream stream, Type type) throws IOException {
+         try {
+            return (V) 
json.fromJson(this.parseService.parse(Strings2.toStringAndClose(stream), 
"datacenters", "dataCenterId"), type);
+         } finally {
+            if (stream != null) {
+               stream.close();
+            }
+         }
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/filters/AuthenticateRequest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/filters/AuthenticateRequest.java
 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/filters/AuthenticateRequest.java
index 941387a..bf27231 100644
--- 
a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/filters/AuthenticateRequest.java
+++ 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/filters/AuthenticateRequest.java
@@ -35,12 +35,12 @@ public class AuthenticateRequest implements 
HttpRequestFilter {
    @Inject
    AuthenticateRequest(@Provider Supplier<Credentials> splr) {
       authToken = splr.get();
-      checkNotNull(authToken.identity, "credential returned null");
+      checkNotNull(authToken.credential, "credential returned null");
 
    }
 
    @Override
    public HttpRequest filter(HttpRequest request) throws HttpException {
-      return request.toBuilder().replaceHeader(AuthHeaders.AUTH_TOKEN, 
authToken.identity).build();
+      return request.toBuilder().replaceHeader(AuthHeaders.AUTH_TOKEN, 
authToken.credential).build();
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneHttpErrorHandler.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneHttpErrorHandler.java
 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneHttpErrorHandler.java
index f92927c..e54a18e 100644
--- 
a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneHttpErrorHandler.java
+++ 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneHttpErrorHandler.java
@@ -16,7 +16,9 @@
  */
 package org.apache.jclouds.oneandone.rest.handlers;
 
+import java.io.IOException;
 import javax.inject.Singleton;
+import 
org.apache.jclouds.oneandone.rest.exceptions.OneAndOneRateLimitExceededException;
 import org.jclouds.http.HttpCommand;
 import org.jclouds.http.HttpErrorHandler;
 import org.jclouds.http.HttpResponse;
@@ -25,6 +27,7 @@ import org.jclouds.rest.AuthorizationException;
 import org.jclouds.rest.InsufficientResourcesException;
 import org.jclouds.rest.ResourceNotFoundException;
 import static org.jclouds.util.Closeables2.closeQuietly;
+import org.jclouds.util.Strings2;
 
 @Singleton
 public class OneAndOneHttpErrorHandler implements HttpErrorHandler {
@@ -52,6 +55,9 @@ public class OneAndOneHttpErrorHandler implements 
HttpErrorHandler {
                }
                break;
             case 413:
+            case 429:
+               exception = new OneAndOneRateLimitExceededException(response);
+               break;
             case 503:
                // if nothing (default message was OK) was parsed from command 
executor, assume it was an 503 (Maintenance) html response.
                if (response.getMessage().equals("OK")) {
@@ -61,7 +67,9 @@ public class OneAndOneHttpErrorHandler implements 
HttpErrorHandler {
                }
                break;
             default:
-               exception = new HttpResponseException("A generic error 
occured.", command, response);
+               String message = parseMessage(response);
+               exception = message == null ? new 
HttpResponseException(command, response) : new HttpResponseException(
+                       command, response, message);
                break;
          }
       } finally {
@@ -69,4 +77,15 @@ public class OneAndOneHttpErrorHandler implements 
HttpErrorHandler {
          command.setException(exception);
       }
    }
+
+   public String parseMessage(final HttpResponse response) {
+      if (response.getPayload() == null) {
+         return null;
+      }
+      try {
+         return Strings2.toStringAndClose(response.getPayload().openStream());
+      } catch (IOException e) {
+         throw new RuntimeException(e);
+      }
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneRateLimitRetryHandler.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneRateLimitRetryHandler.java
 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneRateLimitRetryHandler.java
new file mode 100644
index 0000000..f0d98b0
--- /dev/null
+++ 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneRateLimitRetryHandler.java
@@ -0,0 +1,46 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.handlers;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import javax.inject.Singleton;
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.handlers.RateLimitRetryHandler;
+
+@Beta
+@Singleton
+public class OneAndOneRateLimitRetryHandler extends RateLimitRetryHandler {
+
+   public static final String RETRY_AFTER_CUSTOM = "X-Rate-Limit-Reset";
+
+   @Override
+   protected Optional<Long> millisToNextAvailableRequest(HttpCommand command, 
HttpResponse response) {
+
+      String secondsToNextAvailableRequest = 
response.getFirstHeaderOrNull(RETRY_AFTER_CUSTOM);
+      if (secondsToNextAvailableRequest == null) {
+         return Optional.absent();
+      }
+      return 
Optional.of(millisUntilNextAvailableRequest(Long.parseLong(secondsToNextAvailableRequest)));
+
+   }
+
+   public static long millisUntilNextAvailableRequest(long 
secondsToNextAvailableRequest) {
+      return secondsToNextAvailableRequest * 1000;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/Passwords.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/Passwords.java 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/Passwords.java
new file mode 100644
index 0000000..18da47c
--- /dev/null
+++ 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/Passwords.java
@@ -0,0 +1,64 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.util;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Random;
+import java.util.regex.Pattern;
+
+public class Passwords {
+
+   private static final Random random = new Random();
+
+   private static final int MIN_CHAR = 8;
+   private static final int MAX_CHAR = 50;
+   private static final String PASSWORD_FORMAT = String.format(
+           "[a-zA-Z0-9][^iIloOwWyYzZ10]{%d,%d}", MIN_CHAR - 1, MAX_CHAR);
+   private static final Pattern PASSWORD_PATTERN = 
Pattern.compile(PASSWORD_FORMAT);
+
+   private static final ImmutableSet<Character> INVALID_CHARS = 
ImmutableSet.<Character>of(
+           'i', 'I', 'l', 'o', 'O', 'w', 'W', 'y', 'Y', 'z', 'Z', '1', '0');
+
+   public static boolean isValidPassword(String password) {
+      return PASSWORD_PATTERN.matcher(password).matches();
+   }
+
+   public static String generate() {
+      int count = random.nextInt(MAX_CHAR - MIN_CHAR) + MIN_CHAR;
+
+      final char[] buffer = new char[count];
+
+      final int start = 'A';
+      final int end = 'z';
+      final int gap = end - start + 1;
+
+      while (count-- != 0) {
+         char ch = (char) (random.nextInt(gap) + start);
+         if ((isBetween(ch, start, 'Z') || isBetween(ch, 'a', end))
+                 && !INVALID_CHARS.contains(ch)) {
+            buffer[count] = ch;
+         } else {
+            count++;
+         }
+      }
+      return new String(buffer);
+   }
+
+   private static boolean isBetween(char ch, int start, int end) {
+      return ch >= start && ch <= end;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/ServerApplianceParser.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/ServerApplianceParser.java
 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/ServerApplianceParser.java
new file mode 100644
index 0000000..128196b
--- /dev/null
+++ 
b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/ServerApplianceParser.java
@@ -0,0 +1,110 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.util;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.reflect.TypeToken;
+import com.google.gson.internal.LinkedTreeMap;
+import com.google.inject.Inject;
+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.Types;
+import org.jclouds.json.Json;
+
+public class ServerApplianceParser {
+
+   final Json jsonBinder;
+
+   @Inject
+   ServerApplianceParser(Json jsonBinder) {
+      this.jsonBinder = checkNotNull(jsonBinder, "jsonBinder");
+   }
+
+   @SuppressWarnings("serial")
+   public String parse(String json, String prefix, String key) {
+
+      SingleServerAppliance result = null;
+      Type mapType = new TypeToken<Map<String, Object>>() {
+      }.getType();
+      Map<String, Object> jsonMap = jsonBinder.fromJson(json, mapType);
+      List<Object> dcs = cast(jsonMap.get("available_datacenters"));
+      List<Object> categories = cast(jsonMap.get("categories"));
+      Class<? extends Object> typeName = dcs.get(0).getClass();
+      List<SingleServerAppliance.AvailableDataCenters> list = new 
ArrayList<SingleServerAppliance.AvailableDataCenters>();
+      List<String> cats = null;
+
+      if (typeName != String.class) {
+         for (Object t : dcs) {
+            LinkedTreeMap map = (LinkedTreeMap) t;
+            
list.add(SingleServerAppliance.AvailableDataCenters.create(map.get("id").toString(),
 map.get("name").toString()));
+         }
+         if (categories != null) {
+            cats = new ArrayList<String>();
+            for (Object t : categories) {
+               cats.add(t.toString());
+            }
+         }
+
+      } else {
+         for (Object t : dcs) {
+            
list.add(SingleServerAppliance.AvailableDataCenters.create(t.toString(), ""));
+         }
+         if (categories != null) {
+            cats = new ArrayList<String>();
+            for (Object t : categories) {
+               cats.add(t.toString());
+            }
+         }
+      }
+      String osInstallationBase = jsonMap.get("os_installation_base") != null 
? jsonMap.get("os_installation_base").toString() : null;
+      Types.OSFamliyType osFamily = jsonMap.get("os_family") != null ? 
Types.OSFamliyType.fromValue(jsonMap.get("os_family").toString()) : null;
+      String os = jsonMap.get("os") != null ? jsonMap.get("os").toString() : 
null;
+      String osVersion = jsonMap.get("os_version") != null ? 
jsonMap.get("os_version").toString() : null;
+      Types.OSImageType imageType = jsonMap.get("os_image_type") != null ? 
Types.OSImageType.fromValue(jsonMap.get("os_image_type").toString()) : null;
+      Types.ApplianceType type = jsonMap.get("type") != null ? 
Types.ApplianceType.fromValue(jsonMap.get("type").toString()) : null;
+      String state = jsonMap.get("state") != null ? 
jsonMap.get("state").toString() : null;
+      String version = jsonMap.get("version") != null ? 
jsonMap.get("version").toString() : null;
+      String eula_url = jsonMap.get("eula_url") != null ? 
jsonMap.get("eula_url").toString() : null;
+
+      result = SingleServerAppliance.builder().availableDataCenters(list)
+              .categories(cats)
+              .eulaUrl(eula_url)
+              .id(jsonMap.get("id").toString())
+              .minHddSize((int) 
Double.parseDouble(jsonMap.get("min_hdd_size").toString()))
+              .os(os)
+              .name(jsonMap.get("name").toString())
+              .osArchitecture((int) 
Double.parseDouble(jsonMap.get("os_architecture").toString()))
+              .osFamily(osFamily)
+              .osImageType(imageType)
+              .osInstallationBase(osInstallationBase)
+              .osVersion(osVersion)
+              .state(state)
+              .type(type)
+              .version(version)
+              .build();
+
+      return jsonBinder.toJson(result);
+   }
+
+   @SuppressWarnings("unchecked")
+   public static <T extends List<?>> T cast(Object obj) {
+      return (T) obj;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/OneAndOneComputeServiceLiveTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/OneAndOneComputeServiceLiveTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/OneAndOneComputeServiceLiveTest.java
new file mode 100644
index 0000000..9c385f1
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/OneAndOneComputeServiceLiveTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.compute;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import com.google.inject.Module;
+import 
org.apache.jclouds.oneandone.rest.compute.config.OneAndOneRateLimitModule;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.jclouds.compute.domain.ExecResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
+import static org.jclouds.compute.predicates.NodePredicates.inGroup;
+import org.jclouds.logging.config.LoggingModule;
+import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", singleThreaded = true, testName = 
"OneAndOneComputeServiceLiveTest")
+public class OneAndOneComputeServiceLiveTest extends 
BaseComputeServiceLiveTest {
+
+   public OneAndOneComputeServiceLiveTest() {
+      provider = "oneandone";
+   }
+
+   @Override
+   protected Iterable<Module> setupModules() {
+      ImmutableSet.Builder<Module> modules = ImmutableSet.builder();
+      modules.addAll(super.setupModules());
+      modules.add(new OneAndOneRateLimitModule());
+      return modules.build();
+   }
+
+   @Override
+   protected Module getSshModule() {
+      return new SshjSshClientModule();
+   }
+
+   @Override
+   protected LoggingModule getLoggingModule() {
+      return new SLF4JLoggingModule();
+   }
+
+   @Override
+   public void testOptionToNotBlock() throws Exception {
+      // OneAndOne implementation intentionally blocks until the node is 
'AVAILABLE'
+   }
+
+   @Override
+   protected void checkTagsInNodeEquals(NodeMetadata node, 
ImmutableSet<String> tags) {
+      // 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
+   @Test
+   public void testCreateNodeWithCustomHardware() throws Exception {
+      Template template = buildTemplate(templateBuilder()
+              
.hardwareId("automatic:cores=2;ram=2048;disk=20").osVersionMatches("14.04").osFamily(OsFamily.UBUNTU));
+      try {
+         NodeMetadata node = getOnlyElement(client.createNodesInGroup(group + 
"custom", 1, template));
+         assertThat(node.getHardware().getRam()).isEqualTo(2048);
+         assertThat(node.getHardware().getProcessors().size()).isEqualTo(2);
+         
assertThat(node.getHardware().getVolumes().get(0).getSize()).isEqualTo(20.0F);
+         
assertThat(node.getHardware().getId()).isEqualTo("automatic:cores=2.0;ram=2048;disk=20");
+      } finally {
+         client.destroyNodesMatching(inGroup(group + "custom"));
+      }
+   }
+
+   @Test
+   public void testCreateNodeWithCustomHardwareUsingMins() throws Exception {
+      Template template = 
buildTemplate(templateBuilder().hardwareId("automatic:cores=1;ram=512;disk=20")
+              
.minCores(1).minRam(512).minDisk(20).osVersionMatches("14.04").osFamily(OsFamily.UBUNTU));
+      try {
+         NodeMetadata node = getOnlyElement(client.createNodesInGroup(group + 
"custom", 1, template));
+         assertThat(node.getHardware().getRam()).isEqualTo(512);
+         assertThat(node.getHardware().getProcessors().size()).isEqualTo(1);
+         
assertThat(node.getHardware().getVolumes().get(0).getSize()).isEqualTo(20.0F);
+         
assertThat(node.getHardware().getId()).isEqualTo("automatic:cores=1.0;ram=512;disk=20");
+      } finally {
+         client.destroyNodesMatching(inGroup(group + "custom"));
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/OneAndOneTemplateBuilderLiveTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/OneAndOneTemplateBuilderLiveTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/OneAndOneTemplateBuilderLiveTest.java
new file mode 100644
index 0000000..6d07827
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/OneAndOneTemplateBuilderLiveTest.java
@@ -0,0 +1,35 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.compute;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import org.jclouds.compute.internal.BaseTemplateBuilderLiveTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "OneAndOneTemplateBuilderLiveTest", 
singleThreaded = true)
+public class OneAndOneTemplateBuilderLiveTest extends 
BaseTemplateBuilderLiveTest {
+
+   public OneAndOneTemplateBuilderLiveTest() {
+      this.provider = "oneandone";
+   }
+
+   @Override
+   protected Set<String> getIso3166Codes() {
+      return ImmutableSet.of();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/CustomHardwareToHardwareTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/CustomHardwareToHardwareTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/CustomHardwareToHardwareTest.java
new file mode 100644
index 0000000..61074bc
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/CustomHardwareToHardwareTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.compute.function;
+
+import com.google.common.base.Optional;
+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.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 {
+
+   @Test
+   public void testCustomHardwareToHardwareTest() {
+      List<Hdd> hdds = new ArrayList<Hdd>();
+      Hdd hdd = Hdd.create("hdd", 20, true);
+      hdds.add(hdd);
+
+      Hardware hardware = Hardware.create("", 2, 1, 2, hdds);
+
+      int MinRamSize = (int) hardware.ram();
+      if (hardware.ram() < 1) {
+         MinRamSize = 1;
+      }
+      double size = 0d;
+      List<Volume> volumes = new ArrayList<Volume>();
+      for (Hdd _hdd : hardware.hdds()) {
+         size += hdd.size();
+         Volume vol = new VolumeBuilder()
+                 .bootDevice(_hdd.isMain())
+                 .device("hdd")
+                 .type(Volume.Type.LOCAL)
+                 .size((float) _hdd.size())
+                 .build();
+         volumes.add(vol);
+      }
+
+      List<Processor> processors = new ArrayList<Processor>();
+      for (int i = 0; i < hardware.vcore(); i++) {
+         Processor proc = new Processor(hardware.coresPerProcessor(), 1);
+         processors.add(proc);
+      }
+      AutomaticHardwareIdSpec id = 
AutomaticHardwareIdSpec.automaticHardwareIdSpecBuilder(hardware.vcore(), 
MinRamSize, Optional.of((float) size));
+      org.jclouds.compute.domain.Hardware actual = new HardwareBuilder()
+              .ids(id.toString())
+              .ram(MinRamSize)
+              .volumes(volumes)
+              .processors(ImmutableList.copyOf(processors)).build();
+
+      org.jclouds.compute.domain.Hardware expected = new HardwareBuilder()
+              .ids(id.toString())
+              .ram(2)
+              .volumes(volumes)
+              .processors(ImmutableList.copyOf(processors)).build();
+
+      assertEquals(actual, expected);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/HardwareFlavourToHardwareTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/HardwareFlavourToHardwareTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/HardwareFlavourToHardwareTest.java
new file mode 100644
index 0000000..5bcab12
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/HardwareFlavourToHardwareTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.compute.function;
+
+import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.jclouds.oneandone.rest.domain.HardwareFlavour;
+import org.apache.jclouds.oneandone.rest.domain.HardwareFlavour.Hardware.Hdd;
+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 {
+
+   private HardwareFlavourToHardware fnHardware;
+
+   @BeforeTest
+   public void setup() {
+      this.fnHardware = new HardwareFlavourToHardware();
+   }
+
+   @Test
+   public void testHardwareFlavourToHardware() {
+      List<Hdd> sourceHdds = new ArrayList<Hdd>();
+      Hdd sourceHdd = Hdd.create("GB", 40, true);
+      sourceHdds.add(sourceHdd);
+
+      org.apache.jclouds.oneandone.rest.domain.HardwareFlavour.Hardware 
hrdware = 
org.apache.jclouds.oneandone.rest.domain.HardwareFlavour.Hardware.create(null, 
1, 1, 1, sourceHdds);
+      org.apache.jclouds.oneandone.rest.domain.HardwareFlavour hardware = 
HardwareFlavour.create("65929629F35BBFBA63022008F773F3EB", "name", hrdware);
+
+      Hardware actual = fnHardware.apply(hardware);
+
+      int MinRamSize = (int) hardware.hardware().ram();
+      if (hardware.hardware().ram() < 1) {
+         MinRamSize = 1;
+      }
+      List<Volume> volumes = new ArrayList<Volume>();
+      for (HardwareFlavour.Hardware.Hdd hdd : hardware.hardware().hdds()) {
+         Volume vol = new VolumeBuilder()
+                 .bootDevice(hdd.isMain())
+                 .device("hdd")
+                 .type(Volume.Type.LOCAL)
+                 .size((float) hdd.size())
+                 .build();
+         volumes.add(vol);
+      }
+
+      List<Processor> processors = new ArrayList<Processor>();
+      for (int i = 0; i < hardware.hardware().vcore(); i++) {
+         Processor proc = new 
Processor(hardware.hardware().coresPerProcessor(), 1);
+         processors.add(proc);
+      }
+      Hardware expected = new HardwareBuilder()
+              .ids(hardware.id())
+              .name(hardware.name())
+              .ram(MinRamSize)
+              .volumes(volumes)
+              .processors(ImmutableList.copyOf(processors)).build();
+
+      assertEquals(actual, expected);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/HddToVolumeTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/HddToVolumeTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/HddToVolumeTest.java
new file mode 100644
index 0000000..52342a2
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/HddToVolumeTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.compute.function;
+
+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 {
+
+   private HddToVolume fnVolume;
+
+   @BeforeTest
+   public void setup() {
+      this.fnVolume = new HddToVolume();
+   }
+
+   @Test
+   public void testHddToVolume() {
+
+
+      org.apache.jclouds.oneandone.rest.domain.Hdd hdd = 
org.apache.jclouds.oneandone.rest.domain.Hdd.create("some-id", 40, true);
+
+      Volume actual = fnVolume.apply(hdd);
+
+      Volume expected = new VolumeBuilder()
+              .id(hdd.id())
+              .size((float) hdd.size())
+              .bootDevice(hdd.isMain())
+              .durable(true)
+              .type(Volume.Type.LOCAL).build();
+
+      assertEquals(actual, expected);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/ServerToNodeMetadataTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/ServerToNodeMetadataTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/ServerToNodeMetadataTest.java
new file mode 100644
index 0000000..13fd5e6
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/ServerToNodeMetadataTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.compute.function;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.name.Names;
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.jclouds.oneandone.rest.OneAndOneApi;
+import org.apache.jclouds.oneandone.rest.OneAndOneApiMetadata;
+import org.apache.jclouds.oneandone.rest.domain.DataCenter;
+import org.apache.jclouds.oneandone.rest.domain.HardwareFlavour;
+import org.apache.jclouds.oneandone.rest.domain.Server;
+import org.apache.jclouds.oneandone.rest.domain.ServerAppliance;
+import org.apache.jclouds.oneandone.rest.domain.Types;
+import org.apache.jclouds.oneandone.rest.domain.options.GenericQueryOptions;
+import org.apache.jclouds.oneandone.rest.features.DataCenterApi;
+import org.apache.jclouds.oneandone.rest.features.ServerApi;
+import org.apache.jclouds.oneandone.rest.features.ServerApplianceApi;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneApiMockTest;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+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 {
+
+   private ServerToNodeMetadata fnNodeMetadata;
+   private DataCenterApi dataCenterApi;
+   private ServerApplianceApi serverApplianceApi;
+   private ServerApi serverApi;
+
+   @BeforeTest
+   public void setup() {
+      Supplier<Set<? extends Location>> locationsSupply = new Supplier<Set<? 
extends Location>>() {
+
+         @Override
+         public Set<? extends Location> get() {
+            return ImmutableSet.of(
+                    new LocationBuilder()
+                    .id("908DC2072407C94C8054610AD5A53B8C")
+                    .description("us")
+                    .scope(LocationScope.REGION)
+                    .metadata(ImmutableMap.<String, Object>of(
+                            "version", "10",
+                            "state", "AVAILABLE"))
+                    .parent(new LocationBuilder()
+                            .id("de")
+                            .description("Germany")
+                            .scope(LocationScope.PROVIDER)
+                            .build())
+                    .build());
+         }
+      };
+      Supplier<Map<String, ? extends Hardware>> hardwareFlavours = 
Suppliers.<Map<String, ? extends Hardware>>ofInstance(ImmutableMap
+              .<String, Hardware>of("65929629F35BBFBA63022008F773F3EB", new 
HardwareBuilder().id("65929629F35BBFBA63022008F773F3EB").build()));
+
+      Supplier<Map<String, ? extends Image>> images = Suppliers.<Map<String, ? 
extends Image>>ofInstance(ImmutableMap
+              .<String, Image>of("B5F778B85C041347BCDCFC3172AB3F3C", new 
ImageBuilder().id("B5F778B85C041347BCDCFC3172AB3F3C")
+                      
.operatingSystem(OperatingSystem.builder().description("").is64Bit(true).build()).status(Image.Status.AVAILABLE).build()));
+
+      GroupNamingConvention.Factory namingConvention = 
Guice.createInjector(new AbstractModule() {
+         @Override
+         protected void configure() {
+            Names.bindProperties(binder(), new 
OneAndOneApiMetadata().getDefaultProperties());
+         }
+      }).getInstance(GroupNamingConvention.Factory.class);
+
+      api = EasyMock.createMock(OneAndOneApi.class);
+      dataCenterApi = EasyMock.createMock(DataCenterApi.class);
+      serverApi = EasyMock.createMock(ServerApi.class);
+      serverApplianceApi = EasyMock.createMock(ServerApplianceApi.class);
+
+      expect(dataCenterApi.get("908DC2072407C94C8054610AD5A53B8C")).andReturn(
+              DataCenter.create("908DC2072407C94C8054610AD5A53B8C", "usa", 
"US"));
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "B5F778B85C041347BCDCFC3172AB3F3C", null);
+      List<ServerAppliance> appliances = new ArrayList<ServerAppliance>();
+      ServerAppliance appliance = 
ServerAppliance.create("B5F778B85C041347BCDCFC3172AB3F3C", "name", null, 
"empty", Types.OSFamliyType.Linux, "ubuntu",
+              "Ubuntu14.04", 64, Types.OSImageType.Minimal, 20, 
Types.ApplianceType.IMAGE, null, null, null, null);
+      appliances.add(appliance);
+      List<HardwareFlavour.Hardware.Hdd> hdds = new 
ArrayList<HardwareFlavour.Hardware.Hdd>();
+      HardwareFlavour.Hardware.Hdd hdd = 
HardwareFlavour.Hardware.Hdd.create("GB", 30, true);
+      hdds.add(hdd);
+      
expect(serverApi.getHardwareFlavour("3D4C49EAEDD42FBC23DB58FE3DEF464F")).andReturn(
+              HardwareFlavour.create("3D4C49EAEDD42FBC23DB58FE3DEF464F", 
"mock",
+                      
HardwareFlavour.Hardware.create("3D4C49EAEDD42FBC23DB58FE3DEF464F", 1, 1, 0.5, 
hdds)));
+
+      expect(serverApplianceApi.list(options)).andReturn(appliances);
+
+      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(), 
locationsSupply, hardwareFlavours, images, api, namingConvention);
+   }
+
+   @Test
+   public void testServerToNodeMetadata() {
+
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/compute/server.json"))
+      );
+      Server serverObject = api.serverApi().get("mock");
+
+      NodeMetadata expected = fnNodeMetadata.apply(serverObject);
+      assertNotNull(expected);
+
+      NodeMetadata actual = new NodeMetadataBuilder()
+              .group("docker001")
+              .ids(serverObject.id())
+              .name(serverObject.name())
+              .backendStatus("AVAILABLE")
+              .status(NodeMetadata.Status.RUNNING)
+              .hardware(new HardwareBuilder()
+                      .ids("cpu=4,ram=4096,disk=40")
+                      .name("cpu=4,ram=4096,disk=40")
+                      .ram((int) serverObject.hardware().ram())
+                      .processor(new 
Processor(serverObject.hardware().coresPerProcessor(), 1d))
+                      .hypervisor("kvm")
+                      .volume(new VolumeBuilder()
+                              .bootDevice(true)
+                              .size(40f)
+                              .id("c04a2198-7e60-4bc0-b869-6e9c9dbcb8e1")
+                              .durable(true)
+                              .type(Volume.Type.LOCAL)
+                              .build())
+                      .build())
+              .operatingSystem(new OperatingSystem.Builder()
+                      .description(OsFamily.LINUX.value())
+                      .family(OsFamily.LINUX)
+                      .build())
+              .location(new LocationBuilder()
+                      .id("908DC2072407C94C8054610AD5A53B8C")
+                      .description("us")
+                      .scope(LocationScope.REGION)
+                      .metadata(ImmutableMap.<String, Object>of(
+                              "version", "10",
+                              "state", "AVAILABLE"))
+                      .parent(new LocationBuilder()
+                              .id("de")
+                              .description("Germany")
+                              .scope(LocationScope.PROVIDER)
+                              .build())
+                      .build())
+              .publicAddresses(ImmutableList.<String>of("173.252.120.6"))
+              .build();
+
+      assertEquals(actual, expected);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/SingleServerApplianceToImageTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/SingleServerApplianceToImageTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/SingleServerApplianceToImageTest.java
new file mode 100644
index 0000000..b03c9eb
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/compute/function/SingleServerApplianceToImageTest.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.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 
{
+
+   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");
+
+      Image actual = fnImage.apply(image);
+
+      Image expected = new ImageBuilder()
+              .ids(image.id())
+              .name(image.name())
+              .status(Image.Status.AVAILABLE)
+              .operatingSystem(OperatingSystem.builder()
+                      .description("Windows 2008R2 - 64 bits (Standard) + SQL 
Server 2012 (Standard)")
+                      .family(OsFamily.WINDOWS)
+                      .version("Windows 2008R2")
+                      .is64Bit(true)
+                      .build())
+              .build();
+
+      assertEquals(actual, expected);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/DataCenterApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/DataCenterApiLiveTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/DataCenterApiLiveTest.java
new file mode 100644
index 0000000..5ac973e
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/DataCenterApiLiveTest.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.apache.jclouds.oneandone.rest.features;
+
+import java.util.List;
+import org.apache.jclouds.oneandone.rest.domain.DataCenter;
+import org.apache.jclouds.oneandone.rest.domain.options.GenericQueryOptions;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneLiveTest;
+import org.testng.Assert;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.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();
+      assertNotNull(dataCenters);
+      currentDataCenter = dataCenters.get(0);
+      assertFalse(dataCenters.isEmpty());
+      Assert.assertTrue(dataCenters.size() > 0);
+   }
+
+   @Test
+   public void testListWithOption() {
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "us", null);
+      List<DataCenter> resultWithQuery = dataCenterApi().list(options);
+
+      assertNotNull(resultWithQuery);
+      assertFalse(resultWithQuery.isEmpty());
+      Assert.assertTrue(resultWithQuery.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testList")
+   public void testGet() {
+      DataCenter result = dataCenterApi().get(currentDataCenter.id());
+
+      assertNotNull(result);
+      assertEquals(result.id(), currentDataCenter.id());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/DataCenterApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/DataCenterApiMockTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/DataCenterApiMockTest.java
new file mode 100644
index 0000000..b702993
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/DataCenterApiMockTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.features;
+
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import java.util.List;
+import org.apache.jclouds.oneandone.rest.domain.DataCenter;
+import org.apache.jclouds.oneandone.rest.domain.options.GenericQueryOptions;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneApiMockTest;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "DataCenterApiMockTest", singleThreaded = 
true)
+public class DataCenterApiMockTest extends BaseOneAndOneApiMockTest {
+
+   private DataCenterApi dataCenterApi() {
+      return api.dataCenterApi();
+   }
+
+   @Test
+   public void testList() throws InterruptedException {
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/datacenter/list.json"))
+      );
+
+      List<DataCenter> dataCenter = dataCenterApi().list();
+
+      assertNotNull(dataCenter);
+      assertEquals(dataCenter.size(), 4);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters");
+   }
+
+   @Test
+   public void testList404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404));
+
+      List<DataCenter> dataCenter = dataCenterApi().list();
+
+      assertNotNull(dataCenter);
+      assertEquals(dataCenter.size(), 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters");
+   }
+
+   @Test
+   public void testListWithOption() throws InterruptedException {
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/datacenter/list.options.json"))
+      );
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "New", null);
+      List<DataCenter> dataCenter = dataCenterApi().list(options);
+
+      assertNotNull(dataCenter);
+      assertEquals(dataCenter.size(), 4);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters?q=New");
+   }
+
+   @Test
+   public void testListWithOption404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404));
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "New", null);
+      List<DataCenter> dataCenter = dataCenterApi().list(options);
+
+      assertNotNull(dataCenter);
+      assertEquals(dataCenter.size(), 0);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters?q=New");
+   }
+
+   public void testGet() throws InterruptedException {
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/datacenter/get.json"))
+      );
+      DataCenter result = dataCenterApi().get("datacenterId");
+
+      assertNotNull(result);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenterId");
+   }
+
+   public void testGet404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404));
+      DataCenter result = dataCenterApi().get("datacenterId");
+
+      assertNull(result);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/datacenters/datacenterId");
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiMockTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiMockTest.java
index b577e1b..e9ca3f5 100644
--- 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiMockTest.java
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiMockTest.java
@@ -742,6 +742,7 @@ public class ServerApiMockTest extends 
BaseOneAndOneApiMockTest {
               null,
               null,
               null,
+              null,
               null));
 
       assertNotNull(response);

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApiLiveTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApiLiveTest.java
new file mode 100644
index 0000000..41a3ab1
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApiLiveTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.features;
+
+import java.util.List;
+import org.apache.jclouds.oneandone.rest.domain.ServerAppliance;
+import org.apache.jclouds.oneandone.rest.domain.SingleServerAppliance;
+import org.apache.jclouds.oneandone.rest.domain.options.GenericQueryOptions;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneLiveTest;
+import org.testng.Assert;
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.Test;
+
+@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();
+      Assert.assertTrue(appliances.size() > 0);
+      currentAppliance = appliances.get(0);
+   }
+
+   public void testListWithOption() {
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "iso", null);
+      List<ServerAppliance> resultWithQuery = 
serverApplianceApi().list(options);
+
+      Assert.assertTrue(resultWithQuery.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testList")
+   public void testGet() {
+      SingleServerAppliance result = 
serverApplianceApi().get(currentAppliance.id());
+
+      assertEquals(result.id(), currentAppliance.id());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApiMockTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApiMockTest.java
new file mode 100644
index 0000000..664bde5
--- /dev/null
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApplianceApiMockTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.apache.jclouds.oneandone.rest.features;
+
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import java.util.List;
+import org.apache.jclouds.oneandone.rest.domain.ServerAppliance;
+import org.apache.jclouds.oneandone.rest.domain.SingleServerAppliance;
+import org.apache.jclouds.oneandone.rest.domain.options.GenericQueryOptions;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneApiMockTest;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "ServerApplianceApiMockTest", singleThreaded 
= true)
+public class ServerApplianceApiMockTest extends BaseOneAndOneApiMockTest {
+
+   private ServerApplianceApi serverApplianceApi() {
+      return api.serverApplianceApi();
+   }
+
+   @Test
+   public void testList() throws InterruptedException {
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/serverappliance/list.json"))
+      );
+
+      List<ServerAppliance> networks = serverApplianceApi().list();
+
+      assertNotNull(networks);
+      assertEquals(networks.size(), 2);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/server_appliances");
+   }
+
+   @Test
+   public void testList404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404));
+
+      List<ServerAppliance> networks = serverApplianceApi().list();
+
+      assertEquals(networks.size(), 0);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/server_appliances");
+   }
+
+   @Test
+   public void testListWithOption() throws InterruptedException {
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/serverappliance/list.options.json"))
+      );
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "New", null);
+      List<ServerAppliance> publicIps = serverApplianceApi().list(options);
+
+      assertNotNull(publicIps);
+      assertEquals(publicIps.size(), 4);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/server_appliances?q=New");
+   }
+
+   @Test
+   public void testListWithOption404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404));
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "New", null);
+      List<ServerAppliance> publicIps = serverApplianceApi().list(options);
+
+      assertEquals(publicIps.size(), 0);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/server_appliances?q=New");
+   }
+
+   @Test
+   public void testGet() throws InterruptedException {
+      server.enqueue(
+              new 
MockResponse().setBody(stringFromResource("/serverappliance/get.json"))
+      );
+      SingleServerAppliance result = 
serverApplianceApi().get("serverApplianceId");
+
+      assertNotNull(result);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/server_appliances/serverApplianceId");
+   }
+
+   @Test
+   public void testGet404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404));
+      SingleServerAppliance result = 
serverApplianceApi().get("serverApplianceId");
+
+      assertEquals(result, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/server_appliances/serverApplianceId");
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneApiMockTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneApiMockTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneApiMockTest.java
index 1f90aa5..451f184 100644
--- 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneApiMockTest.java
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneApiMockTest.java
@@ -55,7 +55,7 @@ public class BaseOneAndOneApiMockTest {
       server = new MockWebServer();
       server.play();
       ApiContext<OneAndOneApi> ctx = ContextBuilder.newBuilder("oneandone")
-              .credentials("token", "password")
+              .credentials("token", "token")
               .endpoint(url(""))
               .modules(modules)
               .overrides(overrides())

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneLiveTest.java
----------------------------------------------------------------------
diff --git 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneLiveTest.java
 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneLiveTest.java
index ba1fc4e..bd472c4 100644
--- 
a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneLiveTest.java
+++ 
b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/internal/BaseOneAndOneLiveTest.java
@@ -25,8 +25,6 @@ import java.util.Properties;
 import java.util.concurrent.TimeUnit;
 import org.apache.jclouds.oneandone.rest.OneAndOneApi;
 import org.apache.jclouds.oneandone.rest.OneAndOneProviderMetadata;
-import org.apache.jclouds.oneandone.rest.config.OneAndOneConstants;
-import org.apache.jclouds.oneandone.rest.config.OneAndOneProperties;
 import org.apache.jclouds.oneandone.rest.domain.Hardware;
 import org.apache.jclouds.oneandone.rest.domain.Hdd;
 import org.apache.jclouds.oneandone.rest.domain.PrivateNetwork;
@@ -35,6 +33,8 @@ import org.apache.jclouds.oneandone.rest.domain.Types;
 import org.apache.jclouds.oneandone.rest.domain.Vpn;
 import org.apache.jclouds.oneandone.rest.ids.ServerPrivateNetworkRef;
 import org.jclouds.apis.BaseApiLiveTest;
+import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod;
+import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
 import org.jclouds.util.Predicates2;
 import static org.testng.Assert.assertTrue;
 
@@ -43,24 +43,19 @@ public class BaseOneAndOneLiveTest extends 
BaseApiLiveTest<OneAndOneApi> {
    Predicate<Server> waitUntilServerReady;
    Predicate<ServerPrivateNetworkRef> waitUntilPrivateNetworkReady;
    Predicate<Vpn> waitUntilVPNReady;
+   Timeouts timeouts;
+   PollPeriod pollPeriod;
    private static final OneAndOneProviderMetadata METADATA = new 
OneAndOneProviderMetadata();
-   OneAndOneConstants constants;
 
    public BaseOneAndOneLiveTest() {
       provider = "oneandone";
    }
 
    @Override
-   protected Properties setupProperties() {
-      Properties props = super.setupProperties();
-      setIfTestSystemPropertyPresent(props, OneAndOneProperties.AUTH_TOKEN);
-      return props;
-   }
-
-   @Override
    protected OneAndOneApi create(Properties props, Iterable<Module> modules) {
       Injector injector = 
newBuilder().modules(modules).overrides(props).buildInjector();
-      constants = injector.getInstance(OneAndOneConstants.class);
+      timeouts = injector.getInstance(Timeouts.class);
+      pollPeriod = injector.getInstance(PollPeriod.class);
       Predicate<Server> serverAvailableCheck = new Predicate<Server>() {
          @Override
          public boolean apply(Server currentServer) {
@@ -91,9 +86,9 @@ public class BaseOneAndOneLiveTest extends 
BaseApiLiveTest<OneAndOneApi> {
             return result.state() == Types.GenericState.ACTIVE;
          }
       };
-      waitUntilVPNReady = Predicates2.retry(vpnAvailableCheck, 
constants.pollTimeout(), constants.pollPeriod(), constants.pollMaxPeriod(), 
TimeUnit.SECONDS);
-      waitUntilPrivateNetworkReady = 
Predicates2.retry(privateNetworkAvailableCheck, constants.pollTimeout(), 
constants.pollPeriod(), constants.pollMaxPeriod(), TimeUnit.SECONDS);
-      waitUntilServerReady = Predicates2.retry(serverAvailableCheck, 
constants.pollTimeout(), constants.pollPeriod(), constants.pollMaxPeriod(), 
TimeUnit.SECONDS);
+      waitUntilVPNReady = Predicates2.retry(vpnAvailableCheck, 
timeouts.nodeRunning, pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod, 
TimeUnit.SECONDS);
+      waitUntilPrivateNetworkReady = 
Predicates2.retry(privateNetworkAvailableCheck, timeouts.nodeRunning, 
pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod, TimeUnit.SECONDS);
+      waitUntilServerReady = Predicates2.retry(serverAvailableCheck, 
timeouts.nodeRunning, pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod, 
TimeUnit.SECONDS);
 
       return injector.getInstance(OneAndOneApi.class);
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/compute/hardware.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/compute/hardware.json 
b/oneandone/src/test/resources/compute/hardware.json
new file mode 100644
index 0000000..e7c7128
--- /dev/null
+++ b/oneandone/src/test/resources/compute/hardware.json
@@ -0,0 +1,15 @@
+{
+    "id": "65929629F35BBFBA63022008F773F3EB",
+    "name": "M",
+    "hardware": {
+        "vcore": 1,
+        "cores_per_processor": 1,
+        "ram": 1,
+        "unit": "GB",
+        "hdds": [{
+                "size": 40,
+                "unit": "GB",
+                "is_main": true
+            }]
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/compute/image.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/compute/image.json 
b/oneandone/src/test/resources/compute/image.json
new file mode 100644
index 0000000..2baac23
--- /dev/null
+++ b/oneandone/src/test/resources/compute/image.json
@@ -0,0 +1,30 @@
+{
+    "id": "81504C620D98BCEBAA5202D145203B4C",
+    "name": "Windows 2008R2 - 64 bits (Standard) + SQL Server 2012 (Standard)",
+    "available_datacenters":
+            [{
+                    "id": "81DEF28500FBC2A973FC0C620DF5B721",
+                    "name": "La Portalada"
+                }, {
+                    "id": "908DC2072407C94C8054610AD5A53B8C",
+                    "name": "Lenexa (US)"
+                }, {
+                    "id": "4EFAD5836CE43ACA502FD5B99BEE44EF",
+                    "name": "BAP"
+                }, {
+                    "id": "5091F6D8CBFEF9C26ACE957C652D5D49",
+                    "name": "GLO"
+                }],
+    "os_image_type": "Standard",
+    "os_family": "Windows",
+    "os": "Windows",
+    "os_version": "Windows 2008R2",
+    "min_hdd_size": 40,
+    "os_architecture": 64,
+    "licenses": [
+        "Windows",
+        "SQL Server"
+    ],
+    "automatic_installation": true,
+    "type": "IMAGE"
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/compute/server.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/compute/server.json 
b/oneandone/src/test/resources/compute/server.json
new file mode 100644
index 0000000..b3fdbe3
--- /dev/null
+++ b/oneandone/src/test/resources/compute/server.json
@@ -0,0 +1,48 @@
+{
+    "id": "C68F3BB07BCBE6191F0ACE996AE4F4F5",
+    "cloudpanel_id": "14DD4DD",
+    "name": "Docs\/Content Test Server: CentOS 7",
+    "description": "",
+    "datacenter": {
+        "id": "908DC2072407C94C8054610AD5A53B8C",
+        "country_code": "usa",
+        "location": "us"
+    },
+    "creation_date": "2016-05-05T08:51:48+00:00",
+    "first_password": "Wb3MvEJHOv",
+    "status": {
+        "state": "POWERED_ON",
+        "percent": null
+    },
+    "hardware": {
+        "fixed_instance_size_id": "3D4C49EAEDD42FBC23DB58FE3DEF464F",
+        "vcore": 1,
+        "cores_per_processor": 1,
+        "ram": 0.5,
+        "hdds": [{
+                "id": "DD4587ABB3433F93F895638054899F91",
+                "size": 30,
+                "is_main": true
+            }]
+    },
+    "image": {
+        "id": "B5F778B85C041347BCDCFC3172AB3F3C",
+        "name": "centos7-64std"
+    },
+    "dvd": null,
+    "snapshot": null,
+    "ips": [{
+            "id": "5B0BB42CBAF62A454B25D21545CD9ACD",
+            "ip": "70.35.199.18",
+            "type": "IPV4",
+            "reverse_dns": null,
+            "firewall_policy": null,
+            "load_balancers": [{
+                    "id": "13C3F75BA55AF28B8B2B4E508786F48B",
+                    "name": "My Load Balancer 1"
+                }]
+        }],
+    "alerts": [],
+    "monitoring_policy": null,
+    "private_networks": null
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/compute/volume.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/compute/volume.json 
b/oneandone/src/test/resources/compute/volume.json
new file mode 100644
index 0000000..82732d8
--- /dev/null
+++ b/oneandone/src/test/resources/compute/volume.json
@@ -0,0 +1,5 @@
+{
+  "id": "1964560F458D95DE1884E443B00E33E7",
+  "size": 40,
+  "is_main": true
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/datacenter/get.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/datacenter/get.json 
b/oneandone/src/test/resources/datacenter/get.json
new file mode 100644
index 0000000..62d9c4b
--- /dev/null
+++ b/oneandone/src/test/resources/datacenter/get.json
@@ -0,0 +1,6 @@
+{
+    "id": "908DC2072407C94C8054610AD5A53B8C",
+    "location": "USA",
+    "country_code": "US",
+    "default": 0
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/datacenter/list.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/datacenter/list.json 
b/oneandone/src/test/resources/datacenter/list.json
new file mode 100644
index 0000000..05c2e4f
--- /dev/null
+++ b/oneandone/src/test/resources/datacenter/list.json
@@ -0,0 +1,22 @@
+[
+    {
+        "id": "81DEF28500FBC2A973FC0C620DF5B721",
+        "location": "Spain",
+        "country_code": "ES"
+    },
+    {
+        "id": "908DC2072407C94C8054610AD5A53B8C",
+        "location": "United States of America",
+        "country_code": "US"
+    },
+    {
+        "id": "4EFAD5836CE43ACA502FD5B99BEE44EF",
+        "location": "Germany",
+        "country_code": "DE"
+    },
+    {
+        "id": "5091F6D8CBFEF9C26ACE957C652D5D49",
+        "location": "United Kingdom of Great Britain and Northern Ireland",
+        "country_code": "GB"
+    }
+]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/datacenter/list.options.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/datacenter/list.options.json 
b/oneandone/src/test/resources/datacenter/list.options.json
new file mode 100644
index 0000000..05c2e4f
--- /dev/null
+++ b/oneandone/src/test/resources/datacenter/list.options.json
@@ -0,0 +1,22 @@
+[
+    {
+        "id": "81DEF28500FBC2A973FC0C620DF5B721",
+        "location": "Spain",
+        "country_code": "ES"
+    },
+    {
+        "id": "908DC2072407C94C8054610AD5A53B8C",
+        "location": "United States of America",
+        "country_code": "US"
+    },
+    {
+        "id": "4EFAD5836CE43ACA502FD5B99BEE44EF",
+        "location": "Germany",
+        "country_code": "DE"
+    },
+    {
+        "id": "5091F6D8CBFEF9C26ACE957C652D5D49",
+        "location": "United Kingdom of Great Britain and Northern Ireland",
+        "country_code": "GB"
+    }
+]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/serverappliance/get.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/serverappliance/get.json 
b/oneandone/src/test/resources/serverappliance/get.json
new file mode 100644
index 0000000..2baac23
--- /dev/null
+++ b/oneandone/src/test/resources/serverappliance/get.json
@@ -0,0 +1,30 @@
+{
+    "id": "81504C620D98BCEBAA5202D145203B4C",
+    "name": "Windows 2008R2 - 64 bits (Standard) + SQL Server 2012 (Standard)",
+    "available_datacenters":
+            [{
+                    "id": "81DEF28500FBC2A973FC0C620DF5B721",
+                    "name": "La Portalada"
+                }, {
+                    "id": "908DC2072407C94C8054610AD5A53B8C",
+                    "name": "Lenexa (US)"
+                }, {
+                    "id": "4EFAD5836CE43ACA502FD5B99BEE44EF",
+                    "name": "BAP"
+                }, {
+                    "id": "5091F6D8CBFEF9C26ACE957C652D5D49",
+                    "name": "GLO"
+                }],
+    "os_image_type": "Standard",
+    "os_family": "Windows",
+    "os": "Windows",
+    "os_version": "Windows 2008R2",
+    "min_hdd_size": 40,
+    "os_architecture": 64,
+    "licenses": [
+        "Windows",
+        "SQL Server"
+    ],
+    "automatic_installation": true,
+    "type": "IMAGE"
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/serverappliance/list.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/serverappliance/list.json 
b/oneandone/src/test/resources/serverappliance/list.json
new file mode 100644
index 0000000..db0797b
--- /dev/null
+++ b/oneandone/src/test/resources/serverappliance/list.json
@@ -0,0 +1,29 @@
+[{
+        "id": "81504C620D98BCEBAA5202D145203B4B",
+        "name": "Windows 2012",
+        "available_datacenters": ["81DEF28500FBC2A973FC0C620DF5B721", 
"908DC2072407C94C8054610AD5A53B8C", "4EFAD5836CE43ACA502FD5B99BEE44EF", 
"5091F6D8CBFEF9C26ACE957C652D5D49"],
+        "os_family": "Windows",
+        "os": "Windows2012R2",
+        "os_version": "WindowsDatacenter",
+        "os_architecture": 64,
+        "os_image_type": "ISO_OS",
+        "type": "ISO",
+        "min_hdd_size": null,
+        "licenses": [],
+        "version": null,
+        "categories": []
+    }, {
+        "id": "6E1F2C70CCD3EE44ED194F4FFC47C4C9",
+        "name": "w2012r2datacenter64min",
+        "available_datacenters": ["81DEF28500FBC2A973FC0C620DF5B721", 
"908DC2072407C94C8054610AD5A53B8C", "4EFAD5836CE43ACA502FD5B99BEE44EF", 
"5091F6D8CBFEF9C26ACE957C652D5D49"],
+        "os_family": "Windows",
+        "os": "Windows2012R2",
+        "os_version": "WindowsDatacenter",
+        "os_architecture": 64,
+        "os_image_type": "MINIMAL",
+        "type": "IMAGE",
+        "min_hdd_size": 20,
+        "licenses": [],
+        "version": null,
+        "categories": []
+    }]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/eeaa3c66/oneandone/src/test/resources/serverappliance/list.options.json
----------------------------------------------------------------------
diff --git a/oneandone/src/test/resources/serverappliance/list.options.json 
b/oneandone/src/test/resources/serverappliance/list.options.json
new file mode 100644
index 0000000..f324da6
--- /dev/null
+++ b/oneandone/src/test/resources/serverappliance/list.options.json
@@ -0,0 +1,86 @@
+[
+    {
+        "id": "55726DEDA20C99CF6F2AF8F18CAC9963",
+        "name": "w2012r2datacenter64iso",
+        "available_datacenters": [
+            "DA41201B4A006EDE6DA62A5A62A658E7",
+            "47FA5A2D251AE57935E30F9D5AB4F817",
+            "7C5FA1D21B98DE39D7516333AAB7DA54"
+        ],
+        "os_family": "Windows",
+        "os": "WindowsDatacenter",
+        "os_version": "Windows2012R2",
+        "architecture": 64,
+        "os_image_type": "ISO_OS",
+        "type": "ISO",
+        "min_hdd_size": 40,
+        "licenses": null,
+        "automatic_installation": false
+    },
+    {
+        "id": "3CE474D95AF5B0777A3DCE3FE0999F50",
+        "name": "w2012r2datacenter64min",
+        "available_datacenters": [
+            "DA41201B4A006EDE6DA62A5A62A658E7",
+            "47FA5A2D251AE57935E30F9D5AB4F817",
+            "7C5FA1D21B98DE39D7516333AAB7DA54"
+        ],
+        "os_family": "Windows",
+        "os": "WindowsDatacenter",
+        "os_version": "Windows2012R2",
+        "architecture": 64,
+        "os_image_type": "Minimal",
+        "type": "IMAGE",
+        "min_hdd_size": 40,
+        "licenses": [
+            {
+                "name": "Windows 2012 Standard"
+            }
+        ],
+        "automatic_installation": true
+    },
+    {
+        "id": "FBB637F5B6F24186166F70745E47E8AD",
+        "name": "w2012r2datacenter64std",
+        "available_datacenters": [
+            "DA41201B4A006EDE6DA62A5A62A658E7",
+            "47FA5A2D251AE57935E30F9D5AB4F817",
+            "7C5FA1D21B98DE39D7516333AAB7DA54"
+        ],
+        "os_family": "Windows",
+        "os": "WindowsDatacenter",
+        "os_version": "Windows2012R2",
+        "architecture": 64,
+        "os_image_type": "Standard",
+        "type": "IMAGE",
+        "min_hdd_size": 40,
+        "licenses": [
+            {
+                "name": "Windows 2012 Standard"
+            }
+        ],
+        "automatic_installation": true
+    },
+    {
+        "id": "A8CB64D8A8AD781D0F60FAA7EE9EC125",
+        "name": "w2012r2datacenter64std+SQL2012express",
+        "available_datacenters": [
+            "DA41201B4A006EDE6DA62A5A62A658E7",
+            "47FA5A2D251AE57935E30F9D5AB4F817",
+            "7C5FA1D21B98DE39D7516333AAB7DA54"
+        ],
+        "os_family": "Windows",
+        "os": "WindowsDatacenter",
+        "os_version": "Windows2012R2",
+        "architecture": 64,
+        "os_image_type": "Standard",
+        "type": "IMAGE",
+        "min_hdd_size": 40,
+        "licenses": [
+            {
+                "name": "Windows 2012 Standard"
+            }
+        ],
+        "automatic_installation": true
+    }
+]
\ No newline at end of file

Reply via email to