You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2016/07/12 06:34:17 UTC

[2/3] jclouds-labs git commit: JCLOUDS-1124 oneandone-server-api

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/ServerApi.java
----------------------------------------------------------------------
diff --git a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/ServerApi.java b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/ServerApi.java
new file mode 100644
index 0000000..5992f43
--- /dev/null
+++ b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/features/ServerApi.java
@@ -0,0 +1,386 @@
+/*
+ * 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.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.TypeAdapter;
+import com.google.gson.TypeAdapterFactory;
+import com.google.gson.reflect.TypeToken;
+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.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import org.apache.jclouds.oneandone.rest.domain.Dvd;
+import org.apache.jclouds.oneandone.rest.domain.Hardware;
+import org.apache.jclouds.oneandone.rest.domain.HardwareFlavour;
+import org.apache.jclouds.oneandone.rest.domain.Hdd;
+import org.apache.jclouds.oneandone.rest.domain.Image;
+import org.apache.jclouds.oneandone.rest.domain.PrivateNetwork;
+import org.apache.jclouds.oneandone.rest.domain.Server;
+import org.apache.jclouds.oneandone.rest.domain.Server.CreateFixedInstanceServer;
+import org.apache.jclouds.oneandone.rest.domain.Server.CreateServer;
+import org.apache.jclouds.oneandone.rest.domain.ServerFirewallPolicy;
+import org.apache.jclouds.oneandone.rest.domain.ServerIp;
+import org.apache.jclouds.oneandone.rest.domain.ServerLoadBalancer;
+import org.apache.jclouds.oneandone.rest.domain.ServerPrivateNetwork;
+import org.apache.jclouds.oneandone.rest.domain.Snapshot;
+import org.apache.jclouds.oneandone.rest.domain.Status;
+import org.apache.jclouds.oneandone.rest.domain.Types;
+import org.apache.jclouds.oneandone.rest.domain.options.GenericQueryOptions;
+import org.apache.jclouds.oneandone.rest.filters.AuthenticateRequest;
+import org.apache.jclouds.oneandone.rest.util.ServerFirewallPolicyAdapter;
+import org.apache.jclouds.oneandone.rest.util.SnapshotAdapter;
+import org.jclouds.Fallbacks;
+import org.jclouds.http.functions.ParseJson;
+import org.jclouds.json.Json;
+import org.jclouds.rest.annotations.BinderParam;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.binders.BindToJsonPayload;
+import org.jclouds.util.Strings2;
+
+@Path("servers")
+@Produces("application/json")
+@Consumes("application/json")
+@RequestFilters(AuthenticateRequest.class)
+public interface ServerApi extends Closeable {
+
+   @Named("servers:list")
+   @GET
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<Server> list();
+
+   @Named("servers:list")
+   @GET
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+
+   List<Server> list(GenericQueryOptions options);
+
+   @Named("servers:flavours:list")
+   @GET
+   @Path("/fixed_instance_sizes")
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+
+   List<HardwareFlavour> listHardwareFlavours();
+
+   @Named("servers:flavours:get")
+   @GET
+   @Path("fixed_instance_sizes/{id}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   HardwareFlavour getHardwareFlavour(@PathParam("id") String flavourId);
+
+   @Named("servers:get")
+   @GET
+   @Path("/{serverId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   Server get(@PathParam("serverId") String serverId);
+
+   @Named("servers:status:get")
+   @GET
+   @Path("/{serverId}/status")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   Status getStatus(@PathParam("serverId") String serverId);
+
+   @Named("servers:create")
+   @POST
+   Server create(@BinderParam(BindToJsonPayload.class) CreateServer server);
+
+   @Named("servers:fixedinstace:create")
+   @POST
+   Server createFixedInstanceServer(@BinderParam(BindToJsonPayload.class) CreateFixedInstanceServer server);
+
+   @Named("server:update")
+   @PUT
+   @Path("/{serverId}")
+   Server update(@PathParam("serverId") String serverId, @BinderParam(BindToJsonPayload.class) Server.UpdateServer server);
+
+   @Named("server:Status:update")
+   @PUT
+   @Path("/{serverId}/status/action")
+   Server updateStatus(@PathParam("serverId") String serverId, @BinderParam(BindToJsonPayload.class) Server.UpdateStatus server);
+
+   @Named("server:delete")
+   @DELETE
+   @Path("/{serverId}")
+   @MapBinder(BindToJsonPayload.class)
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   Server delete(@PathParam("serverId") String serverId);
+
+   @Named("servers:hardware:get")
+   @GET
+   @Path("/{serverId}/hardware")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   Hardware getHardware(@PathParam("serverId") String serverId);
+
+   @Named("server:hardware:update")
+   @PUT
+   @Path("/{serverId}/hardware")
+   Server updateHardware(@PathParam("serverId") String serverId, @BinderParam(BindToJsonPayload.class) Hardware.UpdateHardware server);
+
+   @Named("servers:hardware:hdd:list")
+   @GET
+   @Path("/{serverId}/hardware/hdds")
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<Hdd> listHdds(@PathParam("serverId") String serverId);
+
+   @Named("servers:hardware:hdds:create")
+   @POST
+   @Path("/{serverId}/hardware/hdds")
+   Server addHdd(@PathParam("serverId") String serverId, @BinderParam(BindToJsonPayload.class) Hdd.CreateHddList hdds);
+
+   @Named("servers:hardware:hdds:get")
+   @GET
+   @Path("/{serverId}/hardware/hdds/{hddId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   Hdd getHdd(@PathParam("serverId") String serverId, @PathParam("hddId") String hddId);
+
+   @Named("server:hardware:hdds:update")
+   @PUT
+   @Path("/{serverId}/hardware/hdds/{hddId}")
+   @MapBinder(BindToJsonPayload.class)
+   Server updateHdd(@PathParam("serverId") String serverId, @PathParam("hddId") String hddId, @PayloadParam("size") double size);
+
+   @Named("server:hardware:hdds:delete")
+   @DELETE
+   @Path("/{serverId}/hardware/hdds/{hddId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   Server deleteHdd(@PathParam("serverId") String serverId, @PathParam("hddId") String hddId);
+
+   @Named("servers:image:get")
+   @GET
+   @Path("/{serverId}/image")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   Image getImage(@PathParam("serverId") String serverId);
+
+   @Named("server:image:update")
+   @PUT
+   @Path("/{serverId}/image")
+   Server.UpdateServerResponse updateImage(@PathParam("serverId") String serverId, @BinderParam(BindToJsonPayload.class) Server.UpdateImage server);
+
+   @Named("servers:ip:list")
+   @GET
+   @Path("/{serverId}/ips")
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<ServerIp> listIps(@PathParam("serverId") String serverId);
+
+   @Named("servers:ip:create")
+   @POST
+   @Path("/{serverId}/ips")
+   @MapBinder(BindToJsonPayload.class)
+   Server addIp(@PathParam("serverId") String serverId, @PayloadParam("type") Types.IPType type);
+
+   @Named("servers:ip:get")
+   @GET
+   @Path("/{serverId}/ips/{ipId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   ServerIp getIp(@PathParam("serverId") String serverId, @PathParam("ipId") String ipId);
+
+   @Named("server:ip:delete")
+   @DELETE
+   @Path("/{serverId}/ips/{ipId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   Server deleteIp(@PathParam("serverId") String serverId, @PathParam("ipId") String ipId);
+
+   @Named("servers:ip:firewallPolicy:list")
+   @GET
+   @Path("/{serverId}/ips/{ipId}/firewall_policy")
+   @ResponseParser(ServerApi.FirewallPolicyListParser.class)
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<ServerFirewallPolicy> listIpFirewallPolicies(@PathParam("serverId") String serverId, @PathParam("ipId") String ipId);
+
+   @Named("servers:ip:firewallPolicy:update")
+   @PUT
+   @Path("/{serverId}/ips/{ipId}/firewall_policy")
+   @MapBinder(BindToJsonPayload.class)
+   Server addFirewallPolicy(@PathParam("serverId") String serverId, @PathParam("ipId") String ipId, @PayloadParam("id") String policyId);
+
+   @Named("servers:ip:firewallPolicy:delete")
+   @DELETE
+   @Path("/{serverId}/ips/{ipId}/firewall_policy")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   Server deleteIpFirewallPolicy(@PathParam("serverId") String serverId, @PathParam("ipId") String ipId);
+
+   @Named("servers:ip:loadBalancer:list")
+   @GET
+   @Path("/{serverId}/ips/{ipId}/load_balancers")
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<ServerLoadBalancer> listIpLoadBalancer(@PathParam("serverId") String serverId, @PathParam("ipId") String ipId);
+
+   @Named("servers:ip:loadBalancer:create")
+   @POST
+   @Path("/{serverId}/ips/{ipId}/load_balancers")
+   @MapBinder(BindToJsonPayload.class)
+   Server addIpLoadBalancer(@PathParam("serverId") String serverId, @PathParam("ipId") String ipId, @PayloadParam("load_balancer_id") String loadBalancerId);
+
+   @Named("servers:ip:loadBalancer:delete")
+   @DELETE
+   @Path("/{serverId}/ips/{ipId}/load_balancers/{loadBalancerId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   Server deleteIpLoadBalancer(@PathParam("serverId") String serverId, @PathParam("ipId") String ipId, @PathParam("loadBalancerId") String loadBalancerId);
+
+   @Named("servers:dvd:get")
+   @GET
+   @Path("/{serverId}/dvd")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   Dvd getDvd(@PathParam("serverId") String serverId);
+
+   @Named("servers:dvd:delete")
+   @DELETE
+   @Path("/{serverId}/dvd")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   Server unloadDvd(@PathParam("serverId") String serverId);
+
+   @Named("servers:dvd:update")
+   @PUT
+   @Path("/{serverId}/dvd")
+   @MapBinder(BindToJsonPayload.class)
+   Server loadDvd(@PathParam("serverId") String serverId, @PayloadParam("id") String dvdId);
+
+   @Named("servers:privatenetwork:list")
+   @GET
+   @Path("/{serverId}/private_networks")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   List<ServerPrivateNetwork> listPrivateNetworks(@PathParam("serverId") String serverId);
+
+   @Named("servers:privatenetwork:create")
+   @POST
+   @Path("/{serverId}/private_networks")
+   @MapBinder(BindToJsonPayload.class)
+   Server assignPrivateNetwork(@PathParam("serverId") String serverId, @PayloadParam("id") String privateNetworkId);
+
+   @Named("servers:privatenetwork:get")
+   @GET
+   @Path("/{serverId}/private_networks/{privateNetworkId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   PrivateNetwork getPrivateNetwork(@PathParam("serverId") String serverId, @PathParam("privateNetworkId") String privateNetworkId);
+
+   @Named("servers:privatenetwork:delete")
+   @DELETE
+   @Path("/{serverId}/private_networks/{privateNetworkId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   Server deletePrivateNetwork(@PathParam("serverId") String serverId, @PathParam("privateNetworkId") String privateNetworkId);
+
+   @Named("servers:snapshot:list")
+   @GET
+   @Path("/{serverId}/snapshots")
+   @ResponseParser(ServerApi.SnapshotListParser.class)
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<Snapshot> listSnapshots(@PathParam("serverId") String serverId);
+
+   @Named("servers:snapshot:create")
+   @POST
+   @Path("/{serverId}/snapshots")
+   Server createSnapshot(@PathParam("serverId") String serverId);
+
+   @Named("servers:snapshot:update")
+   @PUT
+   @Path("/{serverId}/snapshots/{snapshotId}")
+   @MapBinder(BindToJsonPayload.class)
+   Server restoreSnapshot(@PathParam("serverId") String serverId, @PathParam("snapshotId") String snapshotId);
+
+   @Named("servers:snapshot:delete")
+   @DELETE
+   @Path("/{serverId}/snapshots/{snapshotId}")
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   Server deleteSnapshot(@PathParam("serverId") String serverId, @PathParam("snapshotId") String snapshotId);
+
+   @Named("servers:clone:create")
+   @POST
+   @Path("/{serverId}/clone")
+   Server clone(@PathParam("serverId") String serverId, @BinderParam(BindToJsonPayload.class) Server.Clone clone);
+
+   static final class FirewallPolicyListParser extends ParseJson<List<ServerFirewallPolicy>> {
+
+      static final TypeLiteral<List<ServerFirewallPolicy>> list = new TypeLiteral<List<ServerFirewallPolicy>>() {
+      };
+
+      @Inject
+      FirewallPolicyListParser(Json json) {
+         super(json, list);
+      }
+
+      @Override
+      public <V> V apply(InputStream stream, Type type) throws IOException {
+         try {
+            GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapterFactory(new TypeAdapterFactory() {
+               @Override
+               public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> tt) {
+                  return new ServerFirewallPolicyAdapter(tt);
+               }
+            });
+            Gson gson = gsonBuilder.create();
+            return (V) gson.fromJson(Strings2.toStringAndClose(stream), type);
+         } finally {
+            if (stream != null) {
+               stream.close();
+            }
+         }
+      }
+   }
+
+   static final class SnapshotListParser extends ParseJson<List<Snapshot>> {
+
+      static final TypeLiteral<List<Snapshot>> list = new TypeLiteral<List<Snapshot>>() {
+      };
+
+      @Inject
+      SnapshotListParser(Json json) {
+         super(json, list);
+      }
+
+      @Override
+      public <V> V apply(InputStream stream, Type type) throws IOException {
+         try {
+            GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapterFactory(new TypeAdapterFactory() {
+               @Override
+               public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> tt) {
+                  return new SnapshotAdapter(tt);
+               }
+            });
+            Gson gson = gsonBuilder.create();
+            return (V) gson.fromJson(Strings2.toStringAndClose(stream), type);
+         } finally {
+            if (stream != null) {
+               stream.close();
+            }
+         }
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/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
new file mode 100644
index 0000000..941387a
--- /dev/null
+++ b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/filters/AuthenticateRequest.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.filters;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Supplier;
+import com.google.inject.Inject;
+import javax.inject.Singleton;
+import org.apache.jclouds.oneandone.rest.refrence.AuthHeaders;
+import org.jclouds.domain.Credentials;
+import org.jclouds.http.HttpException;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpRequestFilter;
+import org.jclouds.location.Provider;
+
+@Singleton
+public class AuthenticateRequest implements HttpRequestFilter {
+
+   private final Credentials authToken;
+
+   @Inject
+   AuthenticateRequest(@Provider Supplier<Credentials> splr) {
+      authToken = splr.get();
+      checkNotNull(authToken.identity, "credential returned null");
+
+   }
+
+   @Override
+   public HttpRequest filter(HttpRequest request) throws HttpException {
+      return request.toBuilder().replaceHeader(AuthHeaders.AUTH_TOKEN, authToken.identity).build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/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
new file mode 100644
index 0000000..f92927c
--- /dev/null
+++ b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/handlers/OneAndOneHttpErrorHandler.java
@@ -0,0 +1,72 @@
+/*
+ * 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 javax.inject.Singleton;
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpErrorHandler;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.HttpResponseException;
+import org.jclouds.rest.AuthorizationException;
+import org.jclouds.rest.InsufficientResourcesException;
+import org.jclouds.rest.ResourceNotFoundException;
+import static org.jclouds.util.Closeables2.closeQuietly;
+
+@Singleton
+public class OneAndOneHttpErrorHandler implements HttpErrorHandler {
+
+   @Override
+   public void handleError(final HttpCommand command, final HttpResponse response) {
+      Exception exception = null;
+      try {
+         switch (response.getStatusCode()) {
+            case 400:
+            case 405:
+               exception = new IllegalArgumentException(response.getMessage(), exception);
+               break;
+            case 401:
+               exception = new AuthorizationException("This request requires authentication.", exception);
+               break;
+            case 402:
+            case 409:
+               exception = new IllegalStateException(response.getMessage(), exception);
+               break;
+            case 404:
+            case 410:
+               if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
+                  exception = new ResourceNotFoundException(response.getMessage(), exception);
+               }
+               break;
+            case 413:
+            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")) {
+                  exception = new HttpResponseException("The OneAndOne team is currently carrying out maintenance.", command, response);
+               } else {
+                  exception = new InsufficientResourcesException(response.getMessage(), exception);
+               }
+               break;
+            default:
+               exception = new HttpResponseException("A generic error occured.", command, response);
+               break;
+         }
+      } finally {
+         closeQuietly(response.getPayload());
+         command.setException(exception);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/ids/ServerPrivateNetworkRef.java
----------------------------------------------------------------------
diff --git a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/ids/ServerPrivateNetworkRef.java b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/ids/ServerPrivateNetworkRef.java
new file mode 100644
index 0000000..275f9d8
--- /dev/null
+++ b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/ids/ServerPrivateNetworkRef.java
@@ -0,0 +1,31 @@
+/*
+ * 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.ids;
+
+import com.google.auto.value.AutoValue;
+
+@AutoValue
+public abstract class ServerPrivateNetworkRef {
+
+   public abstract String serverId();
+
+   public abstract String privateNetworkId();
+
+   public static ServerPrivateNetworkRef create(String serverId, String privateNetworkId) {
+      return new AutoValue_ServerPrivateNetworkRef(serverId, privateNetworkId);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/refrence/AuthHeaders.java
----------------------------------------------------------------------
diff --git a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/refrence/AuthHeaders.java b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/refrence/AuthHeaders.java
new file mode 100644
index 0000000..917fe9d
--- /dev/null
+++ b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/refrence/AuthHeaders.java
@@ -0,0 +1,26 @@
+/*
+ * 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.refrence;
+
+public final class AuthHeaders {
+
+   public static final String AUTH_TOKEN = "X-TOKEN";
+
+   private AuthHeaders() {
+      throw new AssertionError("intentionally unimplemented");
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/ServerFirewallPolicyAdapter.java
----------------------------------------------------------------------
diff --git a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/ServerFirewallPolicyAdapter.java b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/ServerFirewallPolicyAdapter.java
new file mode 100644
index 0000000..b4594dc
--- /dev/null
+++ b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/ServerFirewallPolicyAdapter.java
@@ -0,0 +1,79 @@
+/*
+ * 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.reflect.TypeToken;
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import com.google.inject.TypeLiteral;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.jclouds.oneandone.rest.domain.ServerFirewallPolicy;
+
+public class ServerFirewallPolicyAdapter<T> extends TypeAdapter<List<T>> {
+
+   private com.google.gson.reflect.TypeToken<T> adapterclass;
+   private Gson gson;
+
+   public ServerFirewallPolicyAdapter(com.google.gson.reflect.TypeToken<T> adapterclass) {
+      this.adapterclass = adapterclass;
+      gson = new Gson();
+
+   }
+
+   static final TypeLiteral<List<ServerFirewallPolicy>> list = new TypeLiteral<List<ServerFirewallPolicy>>() {
+   };
+
+   @Override
+   public List<T> read(JsonReader reader) throws IOException {
+      List<ServerFirewallPolicy> list = new ArrayList<ServerFirewallPolicy>();
+      if (reader.peek() == JsonToken.BEGIN_OBJECT) {
+         Type mapType = new TypeToken<Map<String, Object>>() {
+         }.getType();
+         Map<String, String> jsonMap = gson.fromJson(reader, mapType);
+         ServerFirewallPolicy inning = ServerFirewallPolicy.create(jsonMap.get("id"), jsonMap.get("name"));
+         list.add(inning);
+
+      } else if (reader.peek() == JsonToken.BEGIN_ARRAY) {
+
+         reader.beginArray();
+         while (reader.hasNext()) {
+            Type mapType = new TypeToken<Map<String, Object>>() {
+            }.getType();
+            Map<String, String> jsonMap = gson.fromJson(reader, mapType);
+            ServerFirewallPolicy inning = ServerFirewallPolicy.create(jsonMap.get("id"), jsonMap.get("name"));
+            list.add(inning);
+         }
+         reader.endArray();
+
+      } else {
+         reader.skipValue();
+      }
+      return (List<T>) list;
+   }
+
+   @Override
+   public void write(JsonWriter writer, List<T> t) throws IOException {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/SnapshotAdapter.java
----------------------------------------------------------------------
diff --git a/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/SnapshotAdapter.java b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/SnapshotAdapter.java
new file mode 100644
index 0000000..2923e39
--- /dev/null
+++ b/oneandone/src/main/java/org/apache/jclouds/oneandone/rest/util/SnapshotAdapter.java
@@ -0,0 +1,76 @@
+/*
+ * 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.reflect.TypeToken;
+import com.google.gson.Gson;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+import com.google.inject.TypeLiteral;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.jclouds.oneandone.rest.domain.Snapshot;
+
+public class SnapshotAdapter<T> extends TypeAdapter<List<T>> {
+
+   private com.google.gson.reflect.TypeToken<T> adapterclass;
+   private Gson gson;
+
+   public SnapshotAdapter(com.google.gson.reflect.TypeToken<T> adapterclass) {
+      this.adapterclass = adapterclass;
+      gson = new Gson();
+   }
+
+   static final TypeLiteral<List<Snapshot>> snapshot = new TypeLiteral<List<Snapshot>>() {
+   };
+
+   @Override
+   public List<T> read(JsonReader reader) throws IOException {
+      List<Snapshot> list = new ArrayList<Snapshot>();
+      if (reader.peek() == JsonToken.BEGIN_OBJECT) {
+         Type mapType = new TypeToken<Map<String, Object>>() {
+         }.getType();
+         Map<String, String> jsonMap = gson.fromJson(reader, mapType);
+         Snapshot inning = Snapshot.create(jsonMap.get("id"), jsonMap.get("creation_date"), jsonMap.get("deletion_date"));
+         list.add(inning);
+      } else if (reader.peek() == JsonToken.BEGIN_ARRAY) {
+
+         reader.beginArray();
+         while (reader.hasNext()) {
+            Type mapType = new TypeToken<Map<String, Object>>() {
+            }.getType();
+            Map<String, String> jsonMap = gson.fromJson(reader, mapType);
+            Snapshot inning = Snapshot.create(jsonMap.get("id"), jsonMap.get("creation_date"), jsonMap.get("deletion_date"));
+            list.add(inning);
+         }
+         reader.endArray();
+      } else {
+         reader.skipValue();
+      }
+      return (List<T>) list;
+   }
+
+   @Override
+   public void write(JsonWriter writer, List<T> t) throws IOException {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/OneAndOneProviderMetadataTest.java
----------------------------------------------------------------------
diff --git a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/OneAndOneProviderMetadataTest.java b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/OneAndOneProviderMetadataTest.java
new file mode 100644
index 0000000..e9954c5
--- /dev/null
+++ b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/OneAndOneProviderMetadataTest.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+import org.jclouds.providers.internal.BaseProviderMetadataTest;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "OneAndOneProviderMetadataTest")
+public class OneAndOneProviderMetadataTest extends BaseProviderMetadataTest {
+
+   public OneAndOneProviderMetadataTest() {
+      super(new OneAndOneProviderMetadata(), new OneAndOneApiMetadata());
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiLiveTest.java
----------------------------------------------------------------------
diff --git a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiLiveTest.java b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiLiveTest.java
new file mode 100644
index 0000000..de1ee6f
--- /dev/null
+++ b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiLiveTest.java
@@ -0,0 +1,272 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+import org.apache.jclouds.oneandone.rest.domain.FixedInstanceHardware;
+import org.apache.jclouds.oneandone.rest.domain.Hardware;
+import org.apache.jclouds.oneandone.rest.domain.HardwareFlavour;
+import org.apache.jclouds.oneandone.rest.domain.Hdd;
+import org.apache.jclouds.oneandone.rest.domain.Image;
+import org.apache.jclouds.oneandone.rest.domain.Server;
+import org.apache.jclouds.oneandone.rest.domain.Status;
+import org.apache.jclouds.oneandone.rest.domain.Types;
+import org.apache.jclouds.oneandone.rest.domain.Types.ServerAction;
+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.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", testName = "ServerApiLiveTest")
+public class ServerApiLiveTest extends BaseOneAndOneLiveTest {
+
+   private List<Server> servers;
+   private Server currentServer;
+   private Server fixedInstanceServer;
+   private HardwareFlavour currentFlavour;
+   private Hdd currentHdd;
+   private Image currentImage;
+
+   private ServerApi serverApi() {
+
+      return api.serverApi();
+   }
+
+   @BeforeClass
+   public void setupTest() {
+      currentServer = createServer("jclouds test");
+   }
+
+   @AfterClass(alwaysRun = true)
+   public void teardownTest() throws InterruptedException {
+      //turn on currentServer in order to be able to delete
+      assertNodeAvailable(currentServer);
+      turnOnServer(currentServer.id());
+
+      if (fixedInstanceServer != null) {
+
+         //delete fixed instance server once ready 
+         assertNodeAvailable(fixedInstanceServer);
+         deleteServer(fixedInstanceServer.id());
+      }
+      if (currentServer != null) {
+         //delete currentserver once ready
+         assertNodeAvailable(currentServer);
+         deleteServer(currentServer.id());
+      }
+   }
+
+   @Test(dependsOnMethods = "testListHardwareFlavours")
+   public void testCreateFixedInstanceServer() {
+
+      Server.CreateFixedInstanceServer request = Server.CreateFixedInstanceServer.builder()
+              .name("java test fixed instance")
+              .description("testing with jclouds")
+              .hardware(FixedInstanceHardware.create(currentFlavour.id()))
+              .applianceId("7C5FA1D21B98DE39D7516333AAB7DA54")
+              .password("Test123!")
+              .powerOn(Boolean.TRUE).build();
+      fixedInstanceServer = serverApi().createFixedInstanceServer(request);
+
+      assertNotNull(fixedInstanceServer);
+      assertNotNull(fixedInstanceServer.id());
+      assertEquals(currentFlavour.hardware().vcore(), fixedInstanceServer.hardware().vcore());
+      assertEquals(currentFlavour.hardware().coresPerProcessor(), fixedInstanceServer.hardware().coresPerProcessor());
+      assertEquals(currentFlavour.hardware().ram(), fixedInstanceServer.hardware().ram());
+
+   }
+
+   @Test
+   public void testList() {
+      servers = serverApi().list();
+
+      assertNotNull(servers);
+      Assert.assertTrue(servers.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testList")
+   public void testListWithOption() {
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "test", null);
+      List<Server> serversWithQuery = serverApi().list(options);
+
+      assertNotNull(serversWithQuery);
+      Assert.assertTrue(serversWithQuery.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testListWithOption")
+   public void testGetServer() {
+      Server result = serverApi().get(currentServer.id());
+
+      assertNotNull(result);
+      assertEquals(result.id(), currentServer.id());
+   }
+
+   @Test(dependsOnMethods = "testList")
+   public void testListHardwareFlavours() {
+      List<HardwareFlavour> flavours = serverApi().listHardwareFlavours();
+      currentFlavour = flavours.get(1);
+      assertNotNull(flavours);
+      assertFalse(flavours.isEmpty());
+      Assert.assertTrue(flavours.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testListHardwareFlavours")
+   public void testGetHardwareFlavour() {
+      HardwareFlavour flavours = serverApi().getHardwareFlavour(currentFlavour.id());
+
+      assertNotNull(flavours);
+   }
+
+   @Test(dependsOnMethods = "testList")
+   public void testGetServerStatus() {
+      Status status = serverApi().getStatus(currentServer.id());
+
+      assertNotNull(status);
+   }
+
+   @Test(dependsOnMethods = "testGetServerStatus")
+   public void testGetServerHardware() {
+      Hardware hardware = serverApi().getHardware(currentServer.id());
+
+      assertNotNull(hardware);
+   }
+
+   @Test(dependsOnMethods = "testGetServerStatus")
+   public void testUpdateServer() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      String updatedName = "Updatedjava";
+      String updatedDesc = "Updated desc";
+
+      Server updateResult = serverApi().update(currentServer.id(), Server.UpdateServer.create(updatedName, updatedDesc));
+
+      assertNotNull(updateResult);
+      assertEquals(updateResult.name(), updatedName);
+      assertEquals(updateResult.description(), updatedDesc);
+
+   }
+
+   @Test(dependsOnMethods = "testUpdateStaus")
+   public void testUpdateHardware() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+
+      Server updateResult = serverApi().updateHardware(currentServer.id(), Hardware.UpdateHardware.create(4, 2, 6));
+
+      assertNotNull(updateResult);
+   }
+
+   @Test(dependsOnMethods = "testAddHdds")
+   public void testListHardwareHdds() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      //give time for harddisk to be added
+//        Thread.sleep(60000);
+      List<Hdd> hdds = serverApi().listHdds(currentServer.id());
+      for (Hdd hdd : hdds) {
+         if (!hdd.isMain()) {
+            currentHdd = hdd;
+            break;
+         }
+      }
+      assertNotNull(hdds);
+      assertFalse(hdds.isEmpty());
+      Assert.assertTrue(hdds.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testUpdateHardware")
+   public void testAddHdds() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      List<Hdd.CreateHdd> requestList = new ArrayList<Hdd.CreateHdd>();
+      requestList.add(Hdd.CreateHdd.create(20, Boolean.TRUE));
+      Hdd.CreateHddList request = Hdd.CreateHddList.create(requestList);
+      //double check
+      assertNodeAvailable(currentServer);
+      Server response = serverApi().addHdd(currentServer.id(), request);
+
+      assertNotNull(response);
+      Assert.assertTrue(response.hardware().hdds().size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testListHardwareHdds")
+   public void testGetHdd() throws InterruptedException {
+      Hdd response = serverApi().getHdd(currentServer.id(), currentHdd.id());
+
+      assertNotNull(response);
+      assertEquals(response.size(), currentHdd.size());
+   }
+
+   @Test(dependsOnMethods = "testGetHdd")
+   public void testUpdateHdd() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+
+      Server response = serverApi().updateHdd(currentServer.id(), currentHdd.id(), currentHdd.size() + 20);
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testUpdateHdd")
+   public void testDeleteHdd() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      Hdd hddToDelete = null;
+      List<Hdd> hdds = serverApi().listHdds(currentServer.id());
+      for (Hdd hdd : hdds) {
+         if (!hdd.isMain()) {
+            hddToDelete = hdd;
+            break;
+         }
+      }
+      if (hddToDelete != null) {
+         Server response = serverApi().deleteHdd(currentServer.id(), hddToDelete.id());
+         assertNotNull(response);
+      }
+   }
+
+   @Test(dependsOnMethods = "testDeleteHdd")
+   public void testGetImage() throws InterruptedException {
+      if (fixedInstanceServer != null) {
+         currentImage = serverApi().getImage(fixedInstanceServer.id());
+
+         assertNotNull(currentImage);
+      }
+   }
+
+   @Test(dependsOnMethods = "testGetImage")
+   public void testUpdateImage() throws InterruptedException {
+      if (fixedInstanceServer != null) {
+         assertNodeAvailable(fixedInstanceServer);
+
+         Server.UpdateServerResponse response = serverApi().updateImage(fixedInstanceServer.id(), Server.UpdateImage.create(currentImage.id(), "Test123!"));
+
+         assertNotNull(response);
+      }
+   }
+
+   @Test(dependsOnMethods = "testUpdateServer")
+   public void testUpdateStaus() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+
+      Server updateResult = serverApi().updateStatus(currentServer.id(), Server.UpdateStatus.create(ServerAction.POWER_OFF, Types.ServerActionMethod.HARDWARE));
+      assertNodeAvailable(currentServer);
+
+      assertNotNull(updateResult);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/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
new file mode 100644
index 0000000..b577e1b
--- /dev/null
+++ b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerApiMockTest.java
@@ -0,0 +1,816 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+import org.apache.jclouds.oneandone.rest.domain.Dvd;
+import org.apache.jclouds.oneandone.rest.domain.FixedInstanceHardware;
+import org.apache.jclouds.oneandone.rest.domain.Hardware;
+import org.apache.jclouds.oneandone.rest.domain.HardwareFlavour;
+import org.apache.jclouds.oneandone.rest.domain.Hdd;
+import org.apache.jclouds.oneandone.rest.domain.Image;
+import org.apache.jclouds.oneandone.rest.domain.PrivateNetwork;
+import org.apache.jclouds.oneandone.rest.domain.Server;
+import org.apache.jclouds.oneandone.rest.domain.ServerFirewallPolicy;
+import org.apache.jclouds.oneandone.rest.domain.ServerIp;
+import org.apache.jclouds.oneandone.rest.domain.ServerLoadBalancer;
+import org.apache.jclouds.oneandone.rest.domain.ServerPrivateNetwork;
+import org.apache.jclouds.oneandone.rest.domain.Snapshot;
+import org.apache.jclouds.oneandone.rest.domain.Status;
+import org.apache.jclouds.oneandone.rest.domain.Types;
+import org.apache.jclouds.oneandone.rest.domain.options.GenericQueryOptions;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneApiMockTest;
+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 = "unit", testName = "ServerApiMockTest", singleThreaded = true)
+public class ServerApiMockTest extends BaseOneAndOneApiMockTest {
+
+   @Test
+   public void testList() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/list.json"))
+      );
+
+      List<Server> servers = serverApi().list();
+
+      assertNotNull(servers);
+      assertEquals(servers.size(), 10);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers");
+   }
+
+   @Test
+   public void testList404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404));
+
+      List<Server> servers = serverApi().list();
+
+      assertNotNull(servers);
+      assertEquals(servers.size(), 0);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers");
+   }
+
+   @Test
+   public void testListWithOption() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/list.options-query-test.json"))
+      );
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "test", null);
+      List<Server> servers = serverApi().list(options);
+
+      assertNotNull(servers);
+      assertEquals(servers.size(), 9);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers?q=test");
+   }
+
+   @Test
+   public void testListWithOption404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404)
+      );
+      GenericQueryOptions options = new GenericQueryOptions();
+      options.options(0, 0, null, "test", null);
+      List<Server> servers = serverApi().list(options);
+
+      assertNotNull(servers);
+      assertEquals(servers.size(), 0);
+
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers?q=test");
+   }
+
+   public void testGetServer() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.json"))
+      );
+      Server result = serverApi().get("serverId");
+
+      assertNotNull(result);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId");
+   }
+
+   @Test
+   public void testGetServer404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404)
+      );
+      Server result = serverApi().get("serverId");
+
+      assertEquals(result, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId");
+   }
+
+   @Test
+   public void testListHardwareFlavours() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/list.flavours.json"))
+      );
+      List<HardwareFlavour> flavours = serverApi().listHardwareFlavours();
+
+      assertNotNull(flavours);
+      assertFalse(flavours.isEmpty());
+      Assert.assertTrue(flavours.size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/fixed_instance_sizes");
+   }
+
+   @Test
+   public void testGetHardwareFlavour() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.flavour.json"))
+      );
+      HardwareFlavour flavours = serverApi().getHardwareFlavour("flavourId");
+
+      assertNotNull(flavours);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/fixed_instance_sizes/flavourId");
+   }
+
+   @Test
+   public void testGetServerStatus() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.status.json"))
+      );
+      Status status = serverApi().getStatus("serverId");
+
+      assertNotNull(status);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/status");
+   }
+
+   @Test
+   public void testGetServersHardware() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.hardware.json"))
+      );
+      Hardware hardware = serverApi().getHardware("serverId");
+
+      assertNotNull(hardware);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/hardware");
+   }
+
+   @Test
+   public void testUpdateServer() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+      Server response = serverApi().update("serverId", Server.UpdateServer.create("My Server remame", "My server rename description"));
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "PUT", "/servers/serverId", "{\n"
+              + "  \"name\": \"My Server remame\",\n"
+              + "  \"description\": \"My server rename description\"\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testUpdateHardware() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+      Server response = serverApi().updateHardware("serverId", Hardware.UpdateHardware.create(2.0, 2.0, 2.0));
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "PUT", "/servers/serverId/hardware", "{\n"
+              + "  \"vcore\": 2.0,\n"
+              + "  \"cores_per_processor\": 2.0,\n"
+              + "  \"ram\": 2.0\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testListHardwareHdds() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/list.hardware.hdds.json"))
+      );
+      List<Hdd> hdds = serverApi().listHdds("serverId");
+
+      assertNotNull(hdds);
+      assertFalse(hdds.isEmpty());
+      Assert.assertTrue(hdds.size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/hardware/hdds");
+   }
+
+   @Test
+   public void testAddHdds() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/add.hdds.json"))
+      );
+      List<Hdd.CreateHdd> requestList = new ArrayList<Hdd.CreateHdd>();
+      requestList.add(Hdd.CreateHdd.create(40, Boolean.FALSE));
+      Hdd.CreateHddList request = Hdd.CreateHddList.create(requestList);
+
+      Server response = serverApi().addHdd("serverId", request);
+
+      assertNotNull(response);
+      Assert.assertTrue(response.hardware().hdds().size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "POST", "/servers/serverId/hardware/hdds",
+              "{\n"
+              + "  \"hdds\":[\n"
+              + "  {\n"
+              + "    \"size\": 40,\n"
+              + "    \"is_main\": false\n"
+              + "  }\n"
+              + "  ]\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testGetHdd() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.hdd.json"))
+      );
+      Hdd hdd = serverApi().getHdd("serverId", "hddId");
+
+      assertNotNull(hdd);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/hardware/hdds/hddId");
+   }
+
+   @Test
+   public void testUpdateHdd() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+      Server hdd = serverApi().updateHdd("serverId", "hddId", 60);
+
+      assertNotNull(hdd);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "PUT", "/servers/serverId/hardware/hdds/hddId",
+              "{\n"
+              + "  \"size\": 60\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testDeleteHdd() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/delete.json"))
+      );
+      Server hdd = serverApi().deleteHdd("serverId", "hddId");
+
+      assertNotNull(hdd);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/hardware/hdds/hddId");
+   }
+
+   @Test
+   public void testDeleteHdd404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404));
+      Server hdd = serverApi().deleteHdd("serverId", "hddId");
+
+      assertEquals(hdd, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/hardware/hdds/hddId");
+   }
+
+   @Test
+   public void testGetImage() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.image.json"))
+      );
+      Image image = serverApi().getImage("serverId");
+
+      assertNotNull(image);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/image");
+   }
+
+   @Test
+   public void testUpdateImage() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.image.json"))
+      );
+      Server.UpdateServerResponse hdd = serverApi().updateImage("serverId", Server.UpdateImage.create("id", "password"));
+
+      assertNotNull(hdd);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "PUT", "/servers/serverId/image",
+              "{\n"
+              + "  \"id\": \"id\",\n"
+              + "  \"password\": \"password\"\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testListIps() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/list.ip.json"))
+      );
+      List<ServerIp> ips = serverApi().listIps("serverId");
+
+      assertNotNull(ips);
+      assertFalse(ips.isEmpty());
+      Assert.assertTrue(ips.size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/ips");
+   }
+
+   @Test
+   public void testAddIp() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/add.hdds.json"))
+      );
+
+      Server response = serverApi().addIp("serverId", Types.IPType.IPV4);
+
+      assertNotNull(response);
+      Assert.assertTrue(response.hardware().hdds().size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "POST", "/servers/serverId/ips",
+              "{\n"
+              + "  \"type\": \"IPV4\"\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testGetIp() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.ip.json"))
+      );
+      ServerIp ip = serverApi().getIp("serverId", "ipId");
+
+      assertNotNull(ip);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/ips/ipId");
+   }
+
+   @Test
+   public void testDeleteIp() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/delete.json"))
+      );
+
+      Server hdd = serverApi().deleteIp("serverId", "ipId");
+
+      assertNotNull(hdd);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/ips/ipId");
+   }
+
+   @Test
+   public void testDeleteIp404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404)
+      );
+
+      Server hdd = serverApi().deleteIp("serverId", "ipId");
+
+      assertEquals(hdd, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/ips/ipId");
+   }
+
+   @Test
+   public void testListIpFirewallPolicies() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/list.ip.firewallPolicies.json"))
+      );
+      List<ServerFirewallPolicy> policies = serverApi().listIpFirewallPolicies("serverId", "ipId");
+
+      assertNotNull(policies);
+      assertFalse(policies.isEmpty());
+      Assert.assertTrue(policies.size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/ips/ipId/firewall_policy");
+   }
+
+   @Test
+   public void testAddIpFirewallPolicy() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.json"))
+      );
+
+      Server response = serverApi().addFirewallPolicy("serverId", "ipId", "firewallPolicyId");
+
+      assertNotNull(response);
+      Assert.assertTrue(response.hardware().hdds().size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "PUT", "/servers/serverId/ips/ipId/firewall_policy",
+              "{\n"
+              + "  \"id\": \"firewallPolicyId\"\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testDeleteIpFirewallPolicy() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/delete.json"))
+      );
+      Server response = serverApi().deleteIpFirewallPolicy("serverId", "ipId");
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/ips/ipId/firewall_policy");
+   }
+
+   @Test
+   public void testDeleteIpFirewallPolicy404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404)
+      );
+      Server response = serverApi().deleteIpFirewallPolicy("serverId", "ipId");
+
+      assertEquals(response, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/ips/ipId/firewall_policy");
+   }
+
+   @Test
+   public void testListIpLoadBalancer() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/list.ip.loadBalancers.json"))
+      );
+      List<ServerLoadBalancer> loadBalancers = serverApi().listIpLoadBalancer("serverId", "ipId");
+
+      assertNotNull(loadBalancers);
+      assertFalse(loadBalancers.isEmpty());
+      Assert.assertTrue(loadBalancers.size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/ips/ipId/load_balancers");
+   }
+
+   @Test
+   public void testAddIpLoadBalancer() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.json"))
+      );
+
+      Server response = serverApi().addIpLoadBalancer("serverId", "ipId", "loadBalancerId");
+
+      assertNotNull(response);
+      Assert.assertTrue(response.hardware().hdds().size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "POST", "/servers/serverId/ips/ipId/load_balancers",
+              "{\n"
+              + "  \"load_balancer_id\": \"loadBalancerId\"\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testDeleteIpLoadBalancer() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/delete.json"))
+      );
+      Server response = serverApi().deleteIpLoadBalancer("serverId", "ipId", "loadBalancerId");
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/ips/ipId/load_balancers/loadBalancerId");
+   }
+
+   @Test
+   public void testDeleteIpLoadBalancer404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404)
+      );
+      Server response = serverApi().deleteIpLoadBalancer("serverId", "ipId", "loadBalancerId");
+
+      assertEquals(response, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/ips/ipId/load_balancers/loadBalancerId");
+   }
+
+   @Test
+   public void testGetDvd() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.dvd.json"))
+      );
+      Dvd dvd = serverApi().getDvd("serverId");
+
+      assertNotNull(dvd);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/dvd");
+   }
+
+   @Test
+   public void testLoadDvd() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.json"))
+      );
+
+      Server response = serverApi().loadDvd("serverId", "dvdId");
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "PUT", "/servers/serverId/dvd",
+              "{\n"
+              + "  \"id\": \"dvdId\"\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testDeletedvd() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/delete.json"))
+      );
+      Server response = serverApi().unloadDvd("serverId");
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/dvd");
+   }
+
+   @Test
+   public void testDeletedvd404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404)
+      );
+      Server response = serverApi().unloadDvd("serverId");
+
+      assertEquals(response, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/dvd");
+   }
+
+   @Test
+   public void testListPrivateNetwork() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/list.privatenetwork.json"))
+      );
+      List<ServerPrivateNetwork> privateNetwork = serverApi().listPrivateNetworks("serverId");
+
+      assertNotNull(privateNetwork);
+      assertFalse(privateNetwork.isEmpty());
+      Assert.assertTrue(privateNetwork.size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/private_networks");
+   }
+
+   @Test
+   public void testGetPrivateNetwork() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.privatenetwork.json"))
+      );
+      PrivateNetwork response = serverApi().getPrivateNetwork("serverId", "privateNetworkId");
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/private_networks/privateNetworkId");
+   }
+
+   @Test
+   public void testAssignPrivateNetwork() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+
+      Server response = serverApi().assignPrivateNetwork("serverId", "privateNetworkId");
+
+      assertNotNull(response);
+      Assert.assertTrue(response.hardware().hdds().size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "POST", "/servers/serverId/private_networks",
+              "{\n"
+              + "  \"id\": \"privateNetworkId\"\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testDeletePrivateNetwork() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+      Server response = serverApi().deletePrivateNetwork("serverId", "privateNetworkId");
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/private_networks/privateNetworkId");
+   }
+
+   @Test
+   public void testDeletePrivateNetwork404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404)
+      );
+      Server response = serverApi().deletePrivateNetwork("serverId", "privateNetworkId");
+
+      assertEquals(response, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/private_networks/privateNetworkId");
+   }
+
+   @Test
+   public void testListSnapshot() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/list.snapshot.json"))
+      );
+      List<Snapshot> snapshots = serverApi().listSnapshots("serverId");
+
+      assertNotNull(snapshots);
+      assertFalse(snapshots.isEmpty());
+      Assert.assertTrue(snapshots.size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "GET", "/servers/serverId/snapshots");
+   }
+
+   @Test
+   public void testRestoreSnapshot() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+      Server response = serverApi().restoreSnapshot("serverId", "snapshotId");
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "PUT", "/servers/serverId/snapshots/snapshotId");
+   }
+
+   @Test
+   public void testCreateSnapshot() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+
+      Server response = serverApi().createSnapshot("serverId");
+
+      assertNotNull(response);
+      Assert.assertTrue(response.hardware().hdds().size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "POST", "/servers/serverId/snapshots");
+   }
+
+   @Test
+   public void testDeleteSnapshot() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/delete.json"))
+      );
+      Server response = serverApi().deleteSnapshot("serverId", "snapshotId");
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/snapshots/snapshotId");
+   }
+
+   @Test
+   public void testDeleteSnapshot404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404)
+      );
+      Server response = serverApi().deleteSnapshot("serverId", "snapshotId");
+
+      assertEquals(response, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId/snapshots/snapshotId");
+   }
+
+   @Test
+   public void testCreateClone() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+
+      Server response = serverApi().clone("serverId", Server.Clone.create("datadcenterId", "Copy of My server"));
+
+      assertNotNull(response);
+      Assert.assertTrue(response.hardware().hdds().size() > 0);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "POST", "/servers/serverId/clone",
+              "{\n"
+              + "  \"name\": \"Copy of My server\",\n"
+              + "  \"datacenter_id\": \"datadcenterId\"\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testCreateServer() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+      List<Hdd.CreateHdd> hdds = new ArrayList<Hdd.CreateHdd>();
+      Hdd.CreateHdd hdd = Hdd.CreateHdd.create(50, Boolean.TRUE);
+      hdds.add(hdd);
+
+      Hdd.CreateHddList hddsRequest = Hdd.CreateHddList.create(hdds);
+
+      Hardware.CreateHardware hardware = Hardware.CreateHardware.create(2.0, 2.0, 2.0, hdds);
+      Server response = serverApi().create(Server.CreateServer.create(
+              "My server",
+              "My server description",
+              hardware,
+              "applianceId",
+              "datacenterId",
+              "Test123!",
+              null,
+              Boolean.TRUE,
+              null,
+              null,
+              null,
+              null));
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "POST", "/servers",
+              "{\"name\":\"My server\",\"description\":\"My server description\",\"hardware\":{\"vcore\":2.0,\"cores_per_processor\":2.0,\"ram\":2.0,\"hdds\":[{\"size\":50.0,\"is_main\":true}]},\"appliance_id\":\"applianceId\",\"datacenter_id\":\"datacenterId\",\"password\":\"Test123!\",\"power_on\":true}"
+      );
+   }
+
+   @Test
+   public void testCreateFixedInstanceServer() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/get.json"))
+      );
+      FixedInstanceHardware hardware = FixedInstanceHardware.create("fixedInstanceId");
+      Server response = serverApi().createFixedInstanceServer(Server.CreateFixedInstanceServer.create(
+              "name", "name", hardware, "applianceId", "datacenterId", "password",
+              null, Boolean.TRUE, null, null, null, null));
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "POST", "/servers",
+              "{\"name\":\"name\",\"description\":\"name\",\"hardware\":{\"fixed_instance_size_id\":\"fixedInstanceId\"},\"appliance_id\":\"applianceId\",\"datacenter_id\":\"datacenterId\",\"password\":\"password\",\"power_on\":true}"
+      );
+   }
+
+   @Test
+   public void testUpdateStauts() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/update.json"))
+      );
+      Server response = serverApi().updateStatus("serverId", Server.UpdateStatus.create(Types.ServerAction.POWER_OFF, Types.ServerActionMethod.SOFTWARE));
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "PUT", "/servers/serverId/status/action",
+              "{\n"
+              + "  \"action\": \"POWER_OFF\",\n"
+              + "  \"method\": \"SOFTWARE\"\n"
+              + "}"
+      );
+   }
+
+   @Test
+   public void testDeleteServer() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setBody(stringFromResource("/server/delete.json"))
+      );
+      Server response = serverApi().delete("serverId");
+
+      assertNotNull(response);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId");
+   }
+
+   @Test
+   public void testDeleteServer404() throws InterruptedException {
+      server.enqueue(
+              new MockResponse().setResponseCode(404)
+      );
+      Server response = serverApi().delete("serverId");
+
+      assertEquals(response, null);
+      assertEquals(server.getRequestCount(), 1);
+      assertSent(server, "DELETE", "/servers/serverId");
+   }
+
+   private ServerApi serverApi() {
+      return api.serverApi();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerNetworkApiLiveTest.java
----------------------------------------------------------------------
diff --git a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerNetworkApiLiveTest.java b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerNetworkApiLiveTest.java
new file mode 100644
index 0000000..bd936e0
--- /dev/null
+++ b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerNetworkApiLiveTest.java
@@ -0,0 +1,141 @@
+/*
+ * 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.Server;
+import org.apache.jclouds.oneandone.rest.domain.ServerFirewallPolicy;
+import org.apache.jclouds.oneandone.rest.domain.ServerIp;
+import org.apache.jclouds.oneandone.rest.domain.ServerLoadBalancer;
+import org.apache.jclouds.oneandone.rest.domain.Types;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneLiveTest;
+import org.testng.Assert;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ServerNetworkApiLiveTest extends BaseOneAndOneLiveTest {
+
+   private Server currentServer;
+   private ServerIp currentIP;
+   private ServerFirewallPolicy currentPolicy;
+   private ServerLoadBalancer currentBalancer;
+
+   @BeforeClass
+   public void setupTest() {
+      currentServer = createServer("jclouds network test");
+   }
+
+   @AfterClass(alwaysRun = true)
+   public void teardownTest() throws InterruptedException {
+      deleteIp();
+      //give time for operations to finish
+      if (currentServer != null) {
+         assertNodeAvailable(currentServer);
+         deleteServer(currentServer.id());
+      }
+   }
+
+   private ServerApi serverApi() {
+
+      return api.serverApi();
+   }
+
+   private void deleteIp() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+
+      Server response = serverApi().deleteIp(currentServer.id(), currentIP.id());
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testAddIp")
+   public void testListips() throws InterruptedException {
+      List<ServerIp> ips = serverApi().listIps(currentServer.id());
+      currentIP = ips.get(0);
+      assertNotNull(ips);
+      Assert.assertTrue(ips.size() > 0);
+   }
+
+   @Test
+   public void testAddIp() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+
+      Server response = serverApi().addIp(currentServer.id(), Types.IPType.IPV4);
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testAddIpFirewallPolicy")
+   public void testListipFirewallPolicies() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      List<ServerFirewallPolicy> policies = serverApi().listIpFirewallPolicies(currentServer.id(), currentIP.id());
+      currentPolicy = policies.get(0);
+      assertNotNull(policies);
+      assertFalse(policies.isEmpty());
+      Assert.assertTrue(policies.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testListips")
+   public void testAddIpFirewallPolicy() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      //TODO:: replace with live api data
+      String firewallPolicyId = "34A7E423DA3253E6D38563ED06F1041F";
+
+      Server response = serverApi().addFirewallPolicy(currentServer.id(), currentIP.id(), firewallPolicyId);
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testListipFirewallPolicies")
+   public void testDeleteIpFirewallPolicy() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      Server response = serverApi().deleteIpFirewallPolicy(currentServer.id(), currentIP.id());
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testAddIpLoadBalancer")
+   public void testListipLoadBalancer() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      List<ServerLoadBalancer> balancers = serverApi().listIpLoadBalancer(currentServer.id(), currentIP.id());
+      assertNotNull(balancers);
+      assertFalse(balancers.isEmpty());
+   }
+
+   @Test(dependsOnMethods = "testAddIp")
+   public void testAddIpLoadBalancer() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      //TODO:: replace with live api data
+      String loadBalancerId = "13C3F75BA55AF28B8B2B4E508786F48B";
+
+      Server response = serverApi().addIpLoadBalancer(currentServer.id(), currentIP.id(), loadBalancerId);
+
+      List<ServerLoadBalancer> balancers = serverApi().listIpLoadBalancer(currentServer.id(), currentIP.id());
+      currentBalancer = balancers.get(0);
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testListipLoadBalancer")
+   public void testDeleteIpLoadBalancer() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      Server response = serverApi().deleteIpLoadBalancer(currentServer.id(), currentIP.id(), currentBalancer.id());
+      assertNotNull(response);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/7df28d25/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerOperationsApiLiveTest.java
----------------------------------------------------------------------
diff --git a/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerOperationsApiLiveTest.java b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerOperationsApiLiveTest.java
new file mode 100644
index 0000000..842b61b
--- /dev/null
+++ b/oneandone/src/test/java/org/apache/jclouds/oneandone/rest/features/ServerOperationsApiLiveTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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.Dvd;
+import org.apache.jclouds.oneandone.rest.domain.PrivateNetwork;
+import org.apache.jclouds.oneandone.rest.domain.Server;
+import org.apache.jclouds.oneandone.rest.domain.ServerPrivateNetwork;
+import org.apache.jclouds.oneandone.rest.domain.Snapshot;
+import org.apache.jclouds.oneandone.rest.ids.ServerPrivateNetworkRef;
+import org.apache.jclouds.oneandone.rest.internal.BaseOneAndOneLiveTest;
+import org.testng.Assert;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ServerOperationsApiLiveTest extends BaseOneAndOneLiveTest {
+
+   private Server currentServer;
+   private Server cloneServer;
+
+   private ServerPrivateNetwork currentPrivateNetwork;
+
+   private ServerApi serverApi() {
+
+      return api.serverApi();
+   }
+
+   @BeforeClass
+   public void setupTest() {
+      currentServer = createServer("jclouds operations test");
+   }
+
+   @AfterClass(alwaysRun = true)
+   public void teardownTest() throws InterruptedException {
+      //give time for operations to finish
+//        Thread.sleep(10000);
+      if (currentServer != null) {
+         assertNodeAvailable(currentServer);
+         deleteServer(currentServer.id());
+      }
+      if (cloneServer != null) {
+         assertNodeAvailable(cloneServer);
+         deleteServer(cloneServer.id());
+      }
+   }
+
+   @Test(dependsOnMethods = "testCreateClone")
+   public void testGetDvd() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      Dvd dvd = serverApi().getDvd(currentServer.id());
+
+      assertNotNull(dvd);
+   }
+
+   @Test(dependsOnMethods = "testGetDvd")
+   public void testLoadDvd() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      //TODO: get data from live api
+      String dvdId = "81504C620D98BCEBAA5202D145203B4B";
+      Server response = serverApi().loadDvd(currentServer.id(), dvdId);
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testLoadDvd")
+   public void testUnloadDvd() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      Server response = serverApi().unloadDvd(currentServer.id());
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testAssignPrivateNetwork")
+   public void testListPrivateNetwork() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      List<ServerPrivateNetwork> privateNetworks = serverApi().listPrivateNetworks(currentServer.id());
+      currentPrivateNetwork = privateNetworks.get(0);
+
+      assertNotNull(privateNetworks);
+      assertFalse(privateNetworks.isEmpty());
+      Assert.assertTrue(privateNetworks.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testListPrivateNetwork")
+   public void testGetPrivateNetwork() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      PrivateNetwork privatenetworkd = serverApi().getPrivateNetwork(currentServer.id(), currentPrivateNetwork.id());
+      assertNotNull(privatenetworkd);
+   }
+
+   @Test
+   public void testAssignPrivateNetwork() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      //TODO: replace with live data from api
+      String privateNetworkId = "40D2C8D5029BF03F7C9D02D54C9F237D";
+      Server response = serverApi().assignPrivateNetwork(currentServer.id(), privateNetworkId);
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testGetPrivateNetwork")
+   public void testDeletePrivateNetwork() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      assertPrivateNetworkAvailable(ServerPrivateNetworkRef.create(currentServer.id(), currentPrivateNetwork.id()));
+      assertNodeAvailable(currentServer);
+
+      Server response = serverApi().deletePrivateNetwork(currentServer.id(), currentPrivateNetwork.id());
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testCreateSnapshot")
+   public void testListSnapshot() throws InterruptedException {
+      List<Snapshot> snapshots = serverApi().listSnapshots(currentServer.id());
+
+      assertNotNull(snapshots);
+      assertFalse(snapshots.isEmpty());
+      Assert.assertTrue(snapshots.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testListSnapshot")
+   public void testRestoreSnapshot() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      currentServer = serverApi().get(currentServer.id());
+      Server response = serverApi().restoreSnapshot(currentServer.id(), currentServer.Snapshot().id());
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testDeletePrivateNetwork")
+   public void testCreateSnapshot() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      Server response = serverApi().createSnapshot(currentServer.id());
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testListSnapshot")
+   public void testDeleteSnapshot() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+      Thread.sleep(120000);
+      currentServer = serverApi().get(currentServer.id());
+      Server response = serverApi().deleteSnapshot(currentServer.id(), currentServer.Snapshot().id());
+
+      assertNotNull(response);
+   }
+
+   @Test(dependsOnMethods = "testDeleteSnapshot")
+   public void testCreateClone() throws InterruptedException {
+      assertNodeAvailable(currentServer);
+
+      cloneServer = serverApi().clone(currentServer.id(), Server.Clone.create(currentServer.datacenter().id(), "jclouds clone"));
+
+      assertNotNull(cloneServer);
+   }
+}