You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by de...@apache.org on 2016/02/19 16:33:24 UTC

[14/35] jclouds git commit: Profitbricks Snapshot api

Profitbricks Snapshot api


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

Branch: refs/heads/master
Commit: 36d499b47ff784b6dad1fdf700fa9e84f7359b37
Parents: de2e5e0
Author: jasminSPC <ja...@stackpointcloud.com>
Authored: Mon Mar 2 18:03:54 2015 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Sun Mar 8 21:10:20 2015 +0100

----------------------------------------------------------------------
 .../jclouds/profitbricks/ProfitBricksApi.java   |   5 +-
 .../snapshot/CreateSnapshotRequestBinder.java   |  44 ++
 .../snapshot/RollbackSnapshotRequestBinder.java |  43 ++
 .../snapshot/UpdateSnapshotRequestBinder.java   |  53 +++
 .../internal/ProvisioningStatusAware.java       |   2 +-
 .../ProvisioningStatusPollingPredicate.java     |   2 +
 .../jclouds/profitbricks/domain/Snapshot.java   | 432 +++++++++++++++++++
 .../profitbricks/features/SnapshotApi.java      |  87 ++++
 .../snapshot/BaseSnapshotResponseHandler.java   |  83 ++++
 .../snapshot/SnapshotListResponseHandler.java   |  52 +++
 .../snapshot/SnapshotResponseHandler.java       |  48 +++
 .../CreateSnapshotRequestBinderTest.java        |  47 ++
 .../RollbackSnapshotRequestBinderTest.java      |  47 ++
 .../UpdateSnapshotRequestBinderTest.java        |  60 +++
 .../ProvisioningStatusPollingPredicateTest.java |  33 ++
 .../features/SnapshotApiLiveTest.java           | 132 ++++++
 .../features/SnapshotApiMockTest.java           | 262 +++++++++++
 .../SnapshotListResponseHandlerTest.java        | 100 +++++
 .../snapshot/SnapshotResponseHandlerTest.java   |  76 ++++
 .../test/resources/snapshot/snapshot-create.xml |  11 +
 .../test/resources/snapshot/snapshot-delete.xml |  10 +
 .../resources/snapshot/snapshot-rollback.xml    |  12 +
 .../snapshot/snapshot-state-inprocess.xml       |  27 ++
 .../test/resources/snapshot/snapshot-update.xml |  10 +
 .../src/test/resources/snapshot/snapshot.xml    |  27 ++
 .../src/test/resources/snapshot/snapshots.xml   |  47 ++
 26 files changed, 1750 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksApi.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksApi.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksApi.java
index 49d7e8c..af7a31d 100644
--- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksApi.java
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksApi.java
@@ -17,12 +17,12 @@
 package org.jclouds.profitbricks;
 
 import java.io.Closeable;
-
 import org.jclouds.profitbricks.features.DataCenterApi;
 import org.jclouds.profitbricks.features.FirewallApi;
 import org.jclouds.profitbricks.features.ImageApi;
 import org.jclouds.profitbricks.features.NicApi;
 import org.jclouds.profitbricks.features.ServerApi;
+import org.jclouds.profitbricks.features.SnapshotApi;
 import org.jclouds.profitbricks.features.StorageApi;
 import org.jclouds.rest.annotations.Delegate;
 
@@ -45,4 +45,7 @@ public interface ProfitBricksApi extends Closeable {
 
    @Delegate
    FirewallApi firewallApi();
+
+   @Delegate
+   SnapshotApi snapshotApi();
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinder.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinder.java
new file mode 100644
index 0000000..213a3a8
--- /dev/null
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinder.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.binder.snapshot;
+
+import org.jclouds.profitbricks.binder.BaseProfitBricksRequestBinder;
+import org.jclouds.profitbricks.domain.Snapshot;
+
+import static java.lang.String.format;
+
+public class CreateSnapshotRequestBinder extends BaseProfitBricksRequestBinder<Snapshot.Request.CreatePayload> {
+
+   protected final StringBuilder requestBuilder;
+
+   protected CreateSnapshotRequestBinder() {
+      super("snapshot");
+      this.requestBuilder = new StringBuilder(128);
+   }
+
+   @Override
+   protected String createPayload(Snapshot.Request.CreatePayload payload) {
+      requestBuilder.append("<ws:createSnapshot>")
+	      .append("<request>")
+	      .append(format("<storageId>%s</storageId>", payload.storageId()))
+	      .append(formatIfNotEmpty("<description>%s</description>", payload.description()))
+	      .append(formatIfNotEmpty("<snapshotName>%s</snapshotName>", payload.name()))
+	      .append("</request>")
+	      .append("</ws:createSnapshot>");
+      return requestBuilder.toString();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinder.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinder.java
new file mode 100644
index 0000000..a9997cb
--- /dev/null
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinder.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.binder.snapshot;
+
+import org.jclouds.profitbricks.binder.BaseProfitBricksRequestBinder;
+import org.jclouds.profitbricks.domain.Snapshot;
+
+import static java.lang.String.format;
+
+public class RollbackSnapshotRequestBinder extends BaseProfitBricksRequestBinder<Snapshot.Request.RollbackPayload> {
+
+    protected final StringBuilder requestBuilder;
+
+    protected RollbackSnapshotRequestBinder() {
+        super("snapshot");
+        this.requestBuilder = new StringBuilder(128);
+    }
+
+    @Override
+    protected String createPayload(Snapshot.Request.RollbackPayload payload) {
+        requestBuilder.append("<ws:rollbackSnapshot>")
+                .append("<request>")
+                .append(format("<snapshotId>%s</snapshotId>", payload.snapshotId()))
+                .append(format("<storageId>%s</storageId>", payload.storageId()))
+                .append("</request>")
+                .append("</ws:rollbackSnapshot>");
+        return requestBuilder.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinder.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinder.java
new file mode 100644
index 0000000..e396715
--- /dev/null
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinder.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.binder.snapshot;
+
+import static java.lang.String.format;
+import org.jclouds.profitbricks.binder.BaseProfitBricksRequestBinder;
+import org.jclouds.profitbricks.domain.Snapshot;
+
+public class UpdateSnapshotRequestBinder extends BaseProfitBricksRequestBinder<Snapshot.Request.UpdatePayload> {
+
+   protected final StringBuilder requestBuilder;
+
+   protected UpdateSnapshotRequestBinder() {
+      super("snapshot");
+      this.requestBuilder = new StringBuilder(128);
+   }
+
+   @Override
+   protected String createPayload(Snapshot.Request.UpdatePayload payload) {
+      requestBuilder.append("<ws:updateSnapshot>")
+	      .append("<request>")
+	      .append(format("<snapshotId>%s</snapshotId>", payload.snapshotId()))
+	      .append(format("<description>%s</description>", payload.description()))
+	      .append(format("<snapshotName>%s</snapshotName>", payload.name()))
+	      .append(formatIfNotEmpty("<bootable>%s</bootable>", payload.bootable()))
+	      .append(formatIfNotEmpty("<osType>%s</osType>", payload.osType()))
+	      .append(formatIfNotEmpty("<cpuHotPlug>%s</cpuHotPlug>", payload.cpuHotplug()))
+	      .append(formatIfNotEmpty("<cpuHotUnPlug>%s</cpuHotUnPlug>", payload.cpuHotunplug()))
+	      .append(formatIfNotEmpty("<ramHotPlug>%s</ramHotPlug>", payload.ramHotplug()))
+	      .append(formatIfNotEmpty("<ramHotUnPlug>%s</ramHotUnPlug>", payload.ramHotunplug()))
+	      .append(formatIfNotEmpty("<nicHotPlug>%s</nicHotPlug>", payload.nicHotplug()))
+	      .append(formatIfNotEmpty("<nicHotUnPlug>%s</nicHotUnPlug>", payload.nicHotunplug()))
+	      .append(formatIfNotEmpty("<discVirtioHotPlug>%s</discVirtioHotPlug>", payload.discVirtioHotplug()))
+	      .append(formatIfNotEmpty("<discVirtioHotUnPlug>%s</discVirtioHotUnPlug>", payload.discVirtioHotunplug()))
+	      .append("</request>")
+	      .append("</ws:updateSnapshot>");
+      return requestBuilder.toString();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusAware.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusAware.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusAware.java
index 7a11009..bd00a3d 100644
--- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusAware.java
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusAware.java
@@ -23,5 +23,5 @@ package org.jclouds.profitbricks.compute.internal;
  */
 public enum ProvisioningStatusAware {
 
-   DATACENTER, SERVER, STORAGE, NIC;
+   DATACENTER, SERVER, STORAGE, NIC, SNAPSHOT;
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicate.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicate.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicate.java
index 7606cac..f38abad 100644
--- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicate.java
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicate.java
@@ -54,6 +54,8 @@ public class ProvisioningStatusPollingPredicate implements Predicate<String> {
             return expect == api.storageApi().getStorage(input).state();
          case NIC:
             return expect == api.nicApi().getNic(input).state();
+         case SNAPSHOT:
+            return expect == api.snapshotApi().getSnapshot(input).state();
          default:
             throw new IllegalArgumentException("Unknown domain '" + domain + "'");
       }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Snapshot.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Snapshot.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Snapshot.java
new file mode 100644
index 0000000..3182711
--- /dev/null
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Snapshot.java
@@ -0,0 +1,432 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.javax.annotation.Nullable;
+
+import java.util.Date;
+
+@AutoValue
+public abstract class Snapshot {
+
+   @Nullable
+   public abstract String id();
+
+   @Nullable
+   public abstract String name();
+
+   public abstract float size();
+
+   public abstract boolean bootable();
+
+   @Nullable
+   public abstract String description();
+
+   @Nullable
+   public abstract OsType osType();
+
+   public abstract boolean cpuHotPlug();
+
+   public abstract boolean cpuHotUnPlug();
+
+   public abstract boolean discVirtioHotPlug();
+
+   public abstract boolean discVirtioHotUnPlug();
+
+   public abstract boolean ramHotPlug();
+
+   public abstract boolean ramHotUnPlug();
+
+   public abstract boolean nicHotPlug();
+
+   public abstract boolean nicHotUnPlug();
+
+   @Nullable
+   public abstract Date creationTime();
+
+   @Nullable
+   public abstract Date lastModificationTime();
+
+   @Nullable
+   public abstract ProvisioningState state();
+
+   @Nullable
+   public abstract Location location();
+
+   public static Snapshot create(String id, String name, float size, boolean bootable, String description, OsType osType, boolean cpuHotPlug, boolean cpuHotUnPlug,
+	   boolean discVirtioHotPlug, boolean discVirtioHotUnPlug, boolean ramHotPlug, boolean ramHotUnPlug,
+	   boolean nicHotPlug, boolean nicHotUnPlug, Date creationTime, Date lastModificationTime, ProvisioningState state, Location location) {
+      return new AutoValue_Snapshot(id, name, size, bootable, description, osType, cpuHotPlug, cpuHotUnPlug,
+	      discVirtioHotPlug, discVirtioHotUnPlug, ramHotPlug, ramHotUnPlug,
+	      nicHotPlug, nicHotUnPlug, creationTime, lastModificationTime, state, location);
+   }
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public static class Builder {
+
+      private String id;
+      @Nullable
+      private String name;
+      private float size;
+      private Date creationTime;
+      private Date lastModificationTime;
+      private ProvisioningState state;
+      private boolean bootable;
+      @Nullable
+      private String description;
+      private OsType osType;
+      private boolean cpuHotPlug;
+      private boolean cpuHotUnPlug;
+      private boolean discVirtioHotPlug;
+      private boolean discVirtioHotUnPlug;
+      private boolean ramHotPlug;
+      private boolean ramHotUnPlug;
+      private boolean nicHotPlug;
+      private boolean nicHotUnPlug;
+      private Location location;
+
+      public Builder id(String id) {
+	 this.id = id;
+	 return this;
+      }
+
+      public Builder name(String name) {
+	 this.name = name;
+	 return this;
+      }
+
+      public Builder size(float size) {
+	 this.size = size;
+	 return this;
+      }
+
+      public Builder creationTime(Date creationTime) {
+	 this.creationTime = creationTime;
+	 return this;
+      }
+
+      public Builder lastModificationTime(Date lastModificationTime) {
+	 this.lastModificationTime = lastModificationTime;
+	 return this;
+      }
+
+      public Builder state(ProvisioningState state) {
+	 this.state = state;
+	 return this;
+      }
+
+      public Builder description(String description) {
+	 this.description = description;
+	 return this;
+      }
+
+      public Builder bootable(Boolean bootable) {
+	 this.bootable = bootable;
+	 return this;
+      }
+
+      public Builder osType(OsType osType) {
+	 this.osType = osType;
+	 return this;
+      }
+
+      public Builder cpuHotPlug(boolean cpuHotPlug) {
+	 this.cpuHotPlug = cpuHotPlug;
+	 return this;
+      }
+
+      public Builder cpuHotUnPlug(boolean cpuHotUnPlug) {
+	 this.cpuHotUnPlug = cpuHotUnPlug;
+	 return this;
+      }
+
+      public Builder discVirtioHotPlug(boolean discVirtioHotPlug) {
+	 this.discVirtioHotPlug = discVirtioHotPlug;
+	 return this;
+      }
+
+      public Builder discVirtioHotUnPlug(boolean discVirtioHotUnPlug) {
+	 this.discVirtioHotUnPlug = discVirtioHotUnPlug;
+	 return this;
+      }
+
+      public Builder ramHotPlug(boolean ramHotPlug) {
+	 this.ramHotPlug = ramHotPlug;
+	 return this;
+      }
+
+      public Builder ramHotUnPlug(boolean ramHotUnPlug) {
+	 this.ramHotUnPlug = ramHotUnPlug;
+	 return this;
+      }
+
+      public Builder nicHotPlug(boolean nicHotPlug) {
+	 this.nicHotPlug = nicHotPlug;
+	 return this;
+      }
+
+      public Builder nicHotUnPlug(boolean nicHotUnPlug) {
+	 this.nicHotUnPlug = nicHotUnPlug;
+	 return this;
+      }
+
+      public Builder location(Location location) {
+	 this.location = location;
+	 return this;
+      }
+
+      private Builder fromSnapshot(Snapshot in) {
+	 return this.id(in.id()).name(in.name()).size(in.size()).creationTime(in.creationTime())
+		 .lastModificationTime(in.lastModificationTime()).state(in.state()).bootable(in.bootable()).description(in.description())
+		 .cpuHotPlug(in.cpuHotPlug()).cpuHotUnPlug(in.cpuHotUnPlug()).discVirtioHotPlug(in.discVirtioHotPlug())
+		 .discVirtioHotUnPlug(in.discVirtioHotUnPlug()).ramHotPlug(in.ramHotPlug()).ramHotUnPlug(in.ramHotUnPlug())
+		 .nicHotPlug(in.nicHotPlug()).nicHotUnPlug(in.nicHotUnPlug());
+      }
+
+      public Snapshot build() {
+	 return Snapshot.create(id, name, size, bootable, description, osType, cpuHotPlug, cpuHotUnPlug, discVirtioHotPlug, discVirtioHotUnPlug, ramHotPlug, ramHotUnPlug, nicHotPlug, nicHotUnPlug, creationTime, lastModificationTime, state, location);
+      }
+   }
+
+   public static final class Request {
+
+      public static CreatePayload.Builder creatingBuilder() {
+	 return new CreatePayload.Builder();
+      }
+
+      public static UpdatePayload.Builder updatingBuilder() {
+	 return new UpdatePayload.Builder();
+      }
+
+      public static RollbackPayload.Builder rollbackBuilder() {
+	 return new RollbackPayload.Builder();
+      }
+
+      @AutoValue
+      public abstract static class CreatePayload {
+
+	 public abstract String storageId();
+
+	 public abstract String description();
+
+	 public abstract String name();
+
+	 public static CreatePayload create(String storageId, String description, String name) {
+	    return new AutoValue_Snapshot_Request_CreatePayload(storageId, description, name);
+	 }
+
+	 public static class Builder {
+
+	    private String storageId;
+	    private String description;
+	    private String name;
+
+	    public Builder storageId(String storageId) {
+	       this.storageId = storageId;
+	       return this;
+	    }
+
+	    public Builder description(String description) {
+	       this.description = description;
+	       return this;
+	    }
+
+	    public Builder name(String name) {
+	       this.name = name;
+	       return this;
+	    }
+
+	    public CreatePayload build() {
+	       return CreatePayload.create(storageId, description, name);
+	    }
+	 }
+      }
+
+      @AutoValue
+      public abstract static class UpdatePayload {
+
+	 public abstract String snapshotId();
+
+	 public abstract String description();
+
+	 public abstract String name();
+
+	 public abstract boolean bootable();
+
+	 @Nullable
+	 public abstract OsType osType();
+
+	 public abstract boolean cpuHotplug();
+
+	 public abstract boolean cpuHotunplug();
+
+	 public abstract boolean ramHotplug();
+
+	 public abstract boolean ramHotunplug();
+
+	 public abstract boolean nicHotplug();
+
+	 public abstract boolean nicHotunplug();
+
+	 public abstract boolean discVirtioHotplug();
+
+	 public abstract boolean discVirtioHotunplug();
+
+	 public static UpdatePayload create(String snapshotId, String description, String name, boolean bootable, OsType osType, boolean cpuHotplug, boolean cpuHotunplug, boolean ramHotplug, boolean ramHotunplug, boolean nicHotplug, boolean nicHotunplug, boolean discVirtioHotplug, boolean discVirtioHotunplug) {
+	    return new AutoValue_Snapshot_Request_UpdatePayload(snapshotId, description, name, bootable, osType, cpuHotplug, cpuHotunplug, ramHotplug, ramHotunplug, nicHotplug, nicHotunplug, discVirtioHotplug, discVirtioHotunplug);
+	 }
+
+	 public static class Builder {
+
+	    private String snapshotId;
+
+	    @Nullable
+	    private String description;
+
+	    @Nullable
+	    private String name;
+
+	    private boolean bootable;
+
+	    private OsType osType;
+
+	    private boolean cpuHotplug;
+
+	    private boolean cpuHotunplug;
+
+	    private boolean ramHotplug;
+
+	    private boolean ramHotunplug;
+
+	    private boolean nicHotplug;
+
+	    private boolean nicHotunplug;
+
+	    private boolean discVirtioHotplug;
+
+	    private boolean discVirtioHotunplug;
+
+	    public Builder snapshotId(String snapshotId) {
+	       this.snapshotId = snapshotId;
+	       return this;
+	    }
+
+	    public Builder description(String description) {
+	       this.description = description;
+	       return this;
+	    }
+
+	    public Builder name(String name) {
+	       this.name = name;
+	       return this;
+	    }
+
+	    public Builder bootable(boolean bootable) {
+	       this.bootable = bootable;
+	       return this;
+	    }
+
+	    public Builder osType(OsType osType) {
+	       this.osType = osType;
+	       return this;
+	    }
+
+	    public Builder cpuHotplug(boolean cpuHotplug) {
+	       this.cpuHotplug = cpuHotplug;
+	       return this;
+	    }
+
+	    public Builder cpuHotunplug(boolean cpuHotunplug) {
+	       this.cpuHotunplug = cpuHotunplug;
+	       return this;
+	    }
+
+	    public Builder ramHotplug(boolean ramHotplug) {
+	       this.ramHotplug = ramHotplug;
+	       return this;
+	    }
+
+	    public Builder ramHotunplug(boolean ramHotunplug) {
+	       this.ramHotunplug = ramHotunplug;
+	       return this;
+	    }
+
+	    public Builder nicHotplug(boolean nicHotplug) {
+	       this.nicHotplug = nicHotplug;
+	       return this;
+	    }
+
+	    public Builder nicHotunplug(boolean nicHotunplug) {
+	       this.nicHotunplug = nicHotunplug;
+	       return this;
+	    }
+
+	    public Builder discVirtioHotplug(boolean discVirtioHotplug) {
+	       this.discVirtioHotplug = discVirtioHotplug;
+	       return this;
+	    }
+
+	    public Builder discVirtioHotunplug(boolean discVirtioHotunplug) {
+	       this.discVirtioHotunplug = discVirtioHotunplug;
+	       return this;
+	    }
+
+	    public UpdatePayload build() {
+	       return UpdatePayload.create(snapshotId, description, name, bootable, osType, cpuHotplug, cpuHotunplug, ramHotplug, ramHotunplug, nicHotplug, nicHotunplug, discVirtioHotplug, discVirtioHotunplug);
+	    }
+	 }
+
+      }
+
+      @AutoValue
+      public abstract static class RollbackPayload {
+
+	 public abstract String snapshotId();
+
+	 public abstract String storageId();
+
+	 public static RollbackPayload create(String snapshotId, String storageId) {
+	    return new AutoValue_Snapshot_Request_RollbackPayload(snapshotId, storageId);
+	 }
+
+	 public static class Builder {
+
+	    private String snapshotId;
+
+	    private String storageId;
+
+	    public Builder snapshotId(String snapshotId) {
+	       this.snapshotId = snapshotId;
+	       return this;
+	    }
+
+	    public Builder storageId(String storageId) {
+	       this.storageId = storageId;
+	       return this;
+	    }
+
+	    public RollbackPayload build() {
+	       return RollbackPayload.create(snapshotId, storageId);
+	    }
+	 }
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/features/SnapshotApi.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/features/SnapshotApi.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/features/SnapshotApi.java
new file mode 100644
index 0000000..3faa386
--- /dev/null
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/features/SnapshotApi.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.features;
+
+import java.util.List;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks;
+import org.jclouds.http.filters.BasicAuthentication;
+import org.jclouds.profitbricks.binder.snapshot.CreateSnapshotRequestBinder;
+import org.jclouds.profitbricks.binder.snapshot.RollbackSnapshotRequestBinder;
+import org.jclouds.profitbricks.binder.snapshot.UpdateSnapshotRequestBinder;
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.jclouds.profitbricks.http.filters.ProfitBricksSoapMessageEnvelope;
+import org.jclouds.profitbricks.http.parser.RequestIdOnlyResponseHandler;
+import org.jclouds.profitbricks.http.parser.snapshot.SnapshotResponseHandler;
+import org.jclouds.profitbricks.http.parser.snapshot.SnapshotListResponseHandler;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.Payload;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.XMLResponseParser;
+
+@RequestFilters({BasicAuthentication.class, ProfitBricksSoapMessageEnvelope.class})
+@Consumes(MediaType.TEXT_XML)
+@Produces(MediaType.TEXT_XML)
+public interface SnapshotApi {
+
+   @POST
+   @Named("snapshot:getall")
+   @Payload("<ws:getAllSnapshots/>")
+   @XMLResponseParser(SnapshotListResponseHandler.class)
+   @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+   List<Snapshot> getAllSnapshots();
+
+   @POST
+   @Named("snapshot:get")
+   @Payload("<ws:getSnapshot><snapshotId>{snapshotId}</snapshotId></ws:getSnapshot>")
+   @XMLResponseParser(SnapshotResponseHandler.class)
+   @Fallback(Fallbacks.NullOnNotFoundOr404.class)
+   Snapshot getSnapshot(@PayloadParam("snapshotId") String identifier);
+
+   @POST
+   @Named("snapshot:create")
+   @MapBinder(CreateSnapshotRequestBinder.class)
+   @XMLResponseParser(SnapshotResponseHandler.class)
+   Snapshot createSnapshot(@PayloadParam("snapshot") Snapshot.Request.CreatePayload payload);
+
+   @POST
+   @Named("snapshot:update")
+   @MapBinder(UpdateSnapshotRequestBinder.class)
+   @XMLResponseParser(RequestIdOnlyResponseHandler.class)
+   String updateSnapshot(@PayloadParam("snapshot") Snapshot.Request.UpdatePayload payload);
+
+   @POST
+   @Named("snapshot:delete")
+   @Payload("<ws:deleteSnapshot><snapshotId>{id}</snapshotId></ws:deleteSnapshot>")
+   @Fallback(Fallbacks.FalseOnNotFoundOr404.class)
+   boolean deleteSnapshot(@PayloadParam("id") String id);
+
+   @POST
+   @Named("snapshot:rollback")
+   @MapBinder(RollbackSnapshotRequestBinder.class)
+   @XMLResponseParser(RequestIdOnlyResponseHandler.class)
+   String rollbackSnapshot(@PayloadParam("snapshot") Snapshot.Request.RollbackPayload payload);
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/BaseSnapshotResponseHandler.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/BaseSnapshotResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/BaseSnapshotResponseHandler.java
new file mode 100644
index 0000000..0fa7fd6
--- /dev/null
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/BaseSnapshotResponseHandler.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.jclouds.profitbricks.http.parser.snapshot;
+
+import java.util.Date;
+import org.jclouds.date.DateCodec;
+import org.jclouds.date.DateCodecFactory;
+import org.jclouds.profitbricks.domain.Location;
+import org.jclouds.profitbricks.domain.OsType;
+import org.jclouds.profitbricks.domain.ProvisioningState;
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.jclouds.profitbricks.http.parser.BaseProfitBricksResponseHandler;
+
+public abstract class BaseSnapshotResponseHandler<T> extends BaseProfitBricksResponseHandler<T> {
+
+   protected Snapshot.Builder builder;
+
+   protected final DateCodec dateCodec;
+
+   BaseSnapshotResponseHandler(DateCodecFactory dateCodec) {
+      this.dateCodec = dateCodec.iso8601();
+      this.builder = Snapshot.builder();
+   }
+
+   protected final Date textToIso8601Date() {
+      return dateCodec.toDate(textToStringValue());
+   }
+
+   @Override
+   protected void setPropertyOnEndTag(String qName) {
+      if ("snapshotId".equals(qName))
+	 builder.id(textToStringValue());
+      else if ("snapshotName".equals(qName))
+	 builder.name(textToStringValue());
+      else if ("snapshotSize".equals(qName))
+	 builder.size(textToFloatValue());
+      else if ("osType".equals(qName))
+	 builder.osType(OsType.fromValue(textToStringValue()));
+      else if ("location".equals(qName))
+	 builder.location(Location.fromId(textToStringValue()));
+      else if ("description".equals(qName))
+	 builder.description(qName);
+      else if ("bootable".equals(qName))
+	 builder.bootable(textToBooleanValue());
+      else if ("cpuHotPlug".equals(qName))
+	 builder.cpuHotPlug(textToBooleanValue());
+      else if ("cpuHotUnPlug".equals(qName))
+	 builder.cpuHotUnPlug(textToBooleanValue());
+      else if ("ramHotPlug".equals(qName))
+	 builder.ramHotPlug(textToBooleanValue());
+      else if ("ramHotUnPlug".equals(qName))
+	 builder.ramHotUnPlug(textToBooleanValue());
+      else if ("nicHotPlug".equals(qName))
+	 builder.nicHotPlug(textToBooleanValue());
+      else if ("nicHotUnPlug".equals(qName))
+	 builder.nicHotUnPlug(textToBooleanValue());
+      else if ("discVirtioHotPlug".equals(qName))
+	 builder.discVirtioHotPlug(textToBooleanValue());
+      else if ("discVirtioHotUnPlug".equals(qName))
+	 builder.discVirtioHotUnPlug(textToBooleanValue());
+      else if ("provisioningState".equals(qName))
+	 builder.state(ProvisioningState.fromValue(textToStringValue()));
+      else if ("creationTimestamp".equals(qName))
+	 builder.creationTime(textToIso8601Date());
+      else if ("modificationTimestamp".equals(qName))
+	 builder.lastModificationTime(textToIso8601Date());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandler.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandler.java
new file mode 100644
index 0000000..ae7a355
--- /dev/null
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandler.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.jclouds.profitbricks.http.parser.snapshot;
+
+import com.google.common.collect.Lists;
+import com.google.inject.Inject;
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.xml.sax.SAXException;
+
+import java.util.List;
+import org.jclouds.date.DateCodecFactory;
+
+public class SnapshotListResponseHandler extends BaseSnapshotResponseHandler<List<Snapshot>> {
+
+   private final List<Snapshot> snapshots;
+
+   @Inject
+   SnapshotListResponseHandler(DateCodecFactory dateCodec) {
+      super(dateCodec);
+      this.snapshots = Lists.newArrayList();
+   }
+
+   @Override
+   public void endElement(String uri, String localName, String qName) throws SAXException {
+      setPropertyOnEndTag(qName);
+      if ("return".equals(qName)) {
+	 snapshots.add(builder.build());
+	 builder = Snapshot.builder();
+      }
+      clearTextBuffer();
+   }
+
+   @Override
+   public List<Snapshot> getResult() {
+      return snapshots;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandler.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandler.java
new file mode 100644
index 0000000..84316f8
--- /dev/null
+++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandler.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.http.parser.snapshot;
+
+import com.google.inject.Inject;
+import org.jclouds.date.DateCodecFactory;
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.xml.sax.SAXException;
+
+public class SnapshotResponseHandler extends BaseSnapshotResponseHandler<Snapshot> {
+
+   private boolean done = false;
+
+   @Inject
+   SnapshotResponseHandler(DateCodecFactory dateCodec) {
+      super(dateCodec);
+   }
+
+   @Override
+   public void endElement(String uri, String localName, String qName) throws SAXException {
+      if (done)
+	 return;
+      setPropertyOnEndTag(qName);
+      if ("return".equals(qName))
+	 done = true;
+      clearTextBuffer();
+   }
+
+   @Override
+   public Snapshot getResult() {
+      return builder.build();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinderTest.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinderTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinderTest.java
new file mode 100644
index 0000000..dda2ed6
--- /dev/null
+++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinderTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.binder.snapshot;
+
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+@Test(groups = "unit", testName = "CreateSnapshotRequestBinderTest")
+public class CreateSnapshotRequestBinderTest {
+
+   @Test
+   public void testCreatePayload() {
+      CreateSnapshotRequestBinder binder = new CreateSnapshotRequestBinder();
+
+      Snapshot.Request.CreatePayload payload = Snapshot.Request.CreatePayload.create("123-1233-1324", "describingthesnapshot", "snapshotname");
+
+      String actual = binder.createPayload(payload);
+      assertNotNull(actual, "Binder returned null payload");
+      assertEquals(expectedPayload, actual);
+   }
+
+   private final String expectedPayload
+	   = ("      <ws:createSnapshot>\n"
+	   + "<request>\n"
+	   + "<storageId>123-1233-1324</storageId>\n"
+	   + "<description>describing the snapshot</description>\n"
+	   + "<snapshotName>snapshot name</snapshotName>\n"
+	   + "</request>\n"
+	   + "</ws:createSnapshot>").replaceAll("\\s+", "");
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinderTest.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinderTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinderTest.java
new file mode 100644
index 0000000..206cd79
--- /dev/null
+++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinderTest.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.binder.snapshot;
+
+import org.jclouds.profitbricks.domain.Snapshot;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "RollbackSnapshotRequestBinderTest")
+public class RollbackSnapshotRequestBinderTest {
+
+   @Test
+   public void testRollbackPayload() {
+      RollbackSnapshotRequestBinder binder = new RollbackSnapshotRequestBinder();
+
+      Snapshot.Request.RollbackPayload payload = Snapshot.Request.rollbackBuilder()
+	      .snapshotId("snapshot-id")
+	      .storageId("storage-id")
+	      .build();
+
+      String actual = binder.createPayload(payload);
+      assertNotNull(actual, "Binder returned null payload");
+      assertEquals(expectedPayload, actual);
+   }
+
+   private final String expectedPayload = "<ws:rollbackSnapshot>"
+	   + "<request>"
+	   + "<snapshotId>snapshot-id</snapshotId>"
+	   + "<storageId>storage-id</storageId>"
+	   + "</request>"
+	   + "</ws:rollbackSnapshot>".replaceAll("\\s", "");
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinderTest.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinderTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinderTest.java
new file mode 100644
index 0000000..3acb8e1
--- /dev/null
+++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinderTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.binder.snapshot;
+
+import org.jclouds.profitbricks.domain.OsType;
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+@Test(groups = "unit", testName = "UpdateSnapshotRequestBinderTest")
+public class UpdateSnapshotRequestBinderTest {
+
+   @Test
+   public void testUpdatePayload() {
+      UpdateSnapshotRequestBinder binder = new UpdateSnapshotRequestBinder();
+
+      Snapshot.Request.UpdatePayload payload = Snapshot.Request.UpdatePayload.create("qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh", "description", "snapshot-name", true, OsType.LINUX, true, true, true, true, true, true, true, true);
+
+      String actual = binder.createPayload(payload);
+      assertNotNull(actual, "Binder returned null payload");
+      assertEquals(expectedPayload, actual);
+
+   }
+
+   private final String expectedPayload
+           = "<ws:updateSnapshot>"
+           + "<request>"
+           + "<snapshotId>qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh</snapshotId>"
+           + "<description>description</description>"
+           + "<snapshotName>snapshot-name</snapshotName>"
+           + "<bootable>true</bootable>"
+           + "<osType>LINUX</osType>"
+           + "<cpuHotPlug>true</cpuHotPlug>"
+           + "<cpuHotUnPlug>true</cpuHotUnPlug>"
+           + "<ramHotPlug>true</ramHotPlug>"
+           + "<ramHotUnPlug>true</ramHotUnPlug>"
+           + "<nicHotPlug>true</nicHotPlug>"
+           + "<nicHotUnPlug>true</nicHotUnPlug>"
+           + "<discVirtioHotPlug>true</discVirtioHotPlug>"
+           + "<discVirtioHotUnPlug>true</discVirtioHotUnPlug>"
+           + "</request>"
+           + "</ws:updateSnapshot>".replaceAll("\\s", "");
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicateTest.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicateTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicateTest.java
index f69fc02..857a8ff 100644
--- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicateTest.java
+++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicateTest.java
@@ -136,5 +136,38 @@ public class ProvisioningStatusPollingPredicateTest extends BaseProfitBricksMock
          server.shutdown();
       }
    }
+   
+   @Test
+   public void testSnapshotPredicate() throws Exception{
+        MockWebServer server = mockWebServer();
+
+      byte[] payloadInProcess = payloadFromResource("/snapshot/snapshot-state-inprocess.xml");
+      byte[] payloadAvailable = payloadFromResource("/snapshot/snapshot.xml");
+
+      // wait 3 times
+      server.enqueue(new MockResponse().setBody(payloadInProcess));
+      server.enqueue(new MockResponse().setBody(payloadInProcess));
+      server.enqueue(new MockResponse().setBody(payloadInProcess));
+      server.enqueue(new MockResponse().setBody(payloadAvailable));
+
+      server.enqueue(new MockResponse().setBody(payloadAvailable));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+
+      Predicate<String> waitUntilAvailable = Predicates2.retry(
+              new ProvisioningStatusPollingPredicate(pbApi, ProvisioningStatusAware.SNAPSHOT, ProvisioningState.AVAILABLE),
+              30l, 1l, TimeUnit.SECONDS);
+
+      String id = "qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh";
+      try {
+         waitUntilAvailable.apply(id);
+         ProvisioningState finalState = pbApi.snapshotApi().getSnapshot(id).state();
+         assertRequestHasCommonProperties(server.takeRequest());
+         assertEquals(finalState, ProvisioningState.AVAILABLE);
+      } finally {
+         pbApi.close();
+         server.shutdown();
+      }
+   }
 
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiLiveTest.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiLiveTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiLiveTest.java
new file mode 100644
index 0000000..957555b
--- /dev/null
+++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiLiveTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.features;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.jclouds.profitbricks.BaseProfitBricksLiveTest;
+import org.jclouds.profitbricks.domain.OsType;
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.testng.annotations.Test;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.jclouds.profitbricks.compute.internal.ProvisioningStatusAware;
+import org.jclouds.profitbricks.compute.internal.ProvisioningStatusPollingPredicate;
+import org.jclouds.profitbricks.domain.ProvisioningState;
+import org.jclouds.profitbricks.domain.Storage;
+import org.jclouds.util.Predicates2;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.AfterClass;
+
+@Test(groups = "live", testName = "SnapshotApiLiveTest", singleThreaded = true)
+public class SnapshotApiLiveTest extends BaseProfitBricksLiveTest {
+
+   protected Predicate<String> snapshotWaitingPredicate;
+   private String snapshotId;
+   private String storageId;
+
+   @Override
+   protected void initialize() {
+      super.initialize();
+
+      initializeWaitPredicate();
+
+      List<Storage> storages = api.storageApi().getAllStorages();
+      assertFalse(storages.isEmpty(), "Must atleast have 1 storage available for snapshot testing.");
+
+      storageId = Iterables.getFirst(storages, null).id();
+   }
+
+   @Test
+   public void testCreateSnapshot() {
+      Snapshot snapshot = api.snapshotApi().createSnapshot(Snapshot.Request.CreatePayload.create(storageId, "my description", "test snapshot"));
+
+      assertNotNull(snapshot);
+
+      snapshotWaitingPredicate.apply(snapshot.id());
+
+      snapshotId = snapshot.id();
+   }
+
+   @Test(dependsOnMethods = "testCreateSnapshot")
+   public void testGetAllSnapshots() {
+      List<Snapshot> snapshots = api.snapshotApi().getAllSnapshots();
+
+      assertNotNull(snapshots);
+      assertTrue(snapshots.size() > 0);
+   }
+
+   @Test(dependsOnMethods = "testCreateSnapshot")
+   public void testGetSnapshot() {
+      Snapshot snapshot = api.snapshotApi().getSnapshot(snapshotId);
+
+      assertNotNull(snapshot);
+      assertEquals(snapshot.id(), snapshotId);
+   }
+
+   @Test(dependsOnMethods = "testCreateSnapshot")
+   public void testUpdateSnapshot() {
+
+      String newName = "new name";
+
+      api.snapshotApi().updateSnapshot(Snapshot.Request.updatingBuilder()
+	      .snapshotId(snapshotId)
+	      .description("new description")
+	      .name(newName)
+	      .bootable(true)
+	      .osType(OsType.LINUX)
+	      .cpuHotplug(true)
+	      .cpuHotunplug(true)
+	      .discVirtioHotplug(true)
+	      .discVirtioHotunplug(true)
+	      .nicHotplug(true)
+	      .nicHotunplug(true)
+	      .ramHotplug(true)
+	      .ramHotunplug(true)
+	      .build());
+
+      Snapshot snapshot = api.snapshotApi().getSnapshot(snapshotId);
+
+      assertNotNull(snapshot);
+      assertEquals(snapshot.name(), newName);
+   }
+
+   @Test(dependsOnMethods = "testCreateSnapshot")
+   public void testRollbackSnapshot() {
+      String result = api.snapshotApi().rollbackSnapshot(Snapshot.Request.RollbackPayload.create(snapshotId, storageId));
+
+      assertNotNull(result);
+   }
+
+   @AfterClass(alwaysRun = true)
+   public void testDeleteSnapshot() {
+      boolean result = api.snapshotApi().deleteSnapshot(snapshotId);
+
+      assertTrue(result);
+   }
+
+   private void initializeWaitPredicate() {
+      this.snapshotWaitingPredicate = Predicates2.retry(
+	      new ProvisioningStatusPollingPredicate(api, ProvisioningStatusAware.SNAPSHOT, ProvisioningState.AVAILABLE),
+	      2l * 60l, 2l, TimeUnit.SECONDS);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiMockTest.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiMockTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiMockTest.java
new file mode 100644
index 0000000..80342b0
--- /dev/null
+++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiMockTest.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.features;
+
+import com.squareup.okhttp.mockwebserver.MockResponse;
+import com.squareup.okhttp.mockwebserver.MockWebServer;
+import org.jclouds.profitbricks.ProfitBricksApi;
+import org.jclouds.profitbricks.domain.OsType;
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.jclouds.profitbricks.internal.BaseProfitBricksMockTest;
+import org.testng.annotations.Test;
+
+import java.util.List;
+import static org.jclouds.profitbricks.internal.BaseProfitBricksMockTest.mockWebServer;
+import org.testng.Assert;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * Mock tests for the {@link org.jclouds.profitbricks.features.DataCenterApi} class
+ */
+@Test(groups = "unit", testName = "SnapshotApiMockTest")
+public class SnapshotApiMockTest extends BaseProfitBricksMockTest {
+
+   @Test
+   public void testGetAllSnapshots() throws Exception {
+      MockWebServer server = mockWebServer();
+      server.enqueue(new MockResponse().setBody(payloadFromResource("/snapshot/snapshots.xml")));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+      SnapshotApi api = pbApi.snapshotApi();
+
+      try {
+	 List<Snapshot> snapshots = api.getAllSnapshots();
+	 assertRequestHasCommonProperties(server.takeRequest(), "<ws:getAllSnapshots/>");
+	 assertNotNull(snapshots);
+	 assertEquals(snapshots.size(), 2);
+      } finally {
+	 pbApi.close();
+	 server.shutdown();
+      }
+   }
+
+   @Test
+   public void testGetAllSnapshotsReturning404() throws Exception {
+      MockWebServer server = mockWebServer();
+      server.enqueue(new MockResponse().setResponseCode(404));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+      SnapshotApi api = pbApi.snapshotApi();
+
+      try {
+	 List<Snapshot> snapshots = api.getAllSnapshots();
+	 assertRequestHasCommonProperties(server.takeRequest());
+	 assertTrue(snapshots.isEmpty());
+      } finally {
+	 pbApi.close();
+	 server.shutdown();
+      }
+   }
+
+   @Test
+   public void testGetSnapshot() throws Exception {
+      MockWebServer server = mockWebServer();
+      server.enqueue(new MockResponse().setBody(payloadFromResource("/snapshot/snapshot.xml")));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+      SnapshotApi api = pbApi.snapshotApi();
+
+      String id = "qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh";
+
+      String content = "<ws:getSnapshot><snapshotId>" + id + "</snapshotId></ws:getSnapshot>";
+
+      try {
+	 Snapshot snapshot = api.getSnapshot(id);
+	 assertRequestHasCommonProperties(server.takeRequest(), content);
+	 assertNotNull(snapshot);
+	 assertEquals(snapshot.id(), id);
+      } finally {
+	 pbApi.close();
+	 server.shutdown();
+      }
+   }
+
+   @Test
+   public void testGetNonExistingSnapshot() throws Exception {
+      MockWebServer server = mockWebServer();
+      server.enqueue(new MockResponse().setResponseCode(404));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+      SnapshotApi api = pbApi.snapshotApi();
+
+      String id = "random-non-existing-id";
+      try {
+	 Snapshot snapshot = api.getSnapshot(id);
+	 assertRequestHasCommonProperties(server.takeRequest());
+	 assertNull(snapshot);
+      } finally {
+	 pbApi.close();
+	 server.shutdown();
+      }
+   }
+
+   @Test
+   public void testCreateSnapshot() throws Exception {
+      MockWebServer server = mockWebServer();
+      server.enqueue(new MockResponse().setBody(payloadFromResource("/snapshot/snapshot-create.xml")));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+      SnapshotApi api = pbApi.snapshotApi();
+
+      String storageId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";
+
+      String content = "<ws:createSnapshot>"
+	      + "<request>"
+	      + "<storageId>" + storageId + "</storageId>"
+	      + "<description>description</description>"
+	      + "<snapshotName>snapshot-name</snapshotName>"
+	      + "</request>"
+	      + "</ws:createSnapshot>";
+
+      try {
+	 Snapshot snapshot = api.createSnapshot(
+		 Snapshot.Request.creatingBuilder()
+		 .storageId(storageId)
+		 .description("description")
+		 .name("snapshot-name")
+		 .build());
+	 assertRequestHasCommonProperties(server.takeRequest(), content);
+	 assertNotNull(snapshot.id());
+	 assertEquals(snapshot.id(), "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");
+
+      } finally {
+	 pbApi.close();
+	 server.shutdown();
+      }
+   }
+
+   @Test
+   public void testUpdateSnapshot() throws Exception {
+      MockWebServer server = mockWebServer();
+      server.enqueue(new MockResponse().setBody(payloadFromResource("/snapshot/snapshot-update.xml")));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+      SnapshotApi api = pbApi.snapshotApi();
+
+      String snapshotId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";
+
+      String content = "<ws:updateSnapshot>"
+	      + "<request>"
+	      + "<snapshotId>" + snapshotId + "</snapshotId>"
+	      + "<description>description</description>"
+	      + "<snapshotName>snapshot-name</snapshotName>"
+	      + "<bootable>false</bootable>"
+	      + "<osType>LINUX</osType>"
+	      + "<cpuHotPlug>false</cpuHotPlug>"
+	      + "<cpuHotUnPlug>false</cpuHotUnPlug>"
+	      + "<ramHotPlug>false</ramHotPlug>"
+	      + "<ramHotUnPlug>false</ramHotUnPlug>"
+	      + "<nicHotPlug>false</nicHotPlug>"
+	      + "<nicHotUnPlug>false</nicHotUnPlug>"
+	      + "<discVirtioHotPlug>false</discVirtioHotPlug>"
+	      + "<discVirtioHotUnPlug>false</discVirtioHotUnPlug>"
+	      + "</request>"
+	      + "</ws:updateSnapshot>";
+
+      try {
+	 String requestId = api.updateSnapshot(Snapshot.Request.updatingBuilder()
+		 .snapshotId(snapshotId)
+		 .name("snapshot-name")
+		 .description("description")
+		 .osType(OsType.LINUX)
+		 .build());
+	 assertRequestHasCommonProperties(server.takeRequest(), content);
+	 assertNotNull(requestId);
+      } finally {
+	 pbApi.close();
+	 server.shutdown();
+      }
+   }
+
+   @Test
+   public void testDeleteSnapshot() throws Exception {
+      MockWebServer server = mockWebServer();
+      server.enqueue(new MockResponse().setBody(payloadFromResource("/snapshot/snapshot-delete.xml")));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+      SnapshotApi api = pbApi.snapshotApi();
+
+      String snapshotId = "qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh";
+      String content = "<ws:deleteSnapshot><snapshotId>" + snapshotId + "</snapshotId></ws:deleteSnapshot>";
+
+      try {
+	 boolean result = api.deleteSnapshot(snapshotId);
+	 assertRequestHasCommonProperties(server.takeRequest(), content);
+	 assertTrue(result);
+      } finally {
+	 pbApi.close();
+	 server.shutdown();
+      }
+   }
+
+   @Test
+   public void testDeleteNonExistingSnapshot() throws Exception {
+      MockWebServer server = mockWebServer();
+      server.enqueue(new MockResponse().setResponseCode(404));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+      SnapshotApi api = pbApi.snapshotApi();
+
+      String id = "random-non-existing-id";
+      try {
+	 boolean result = api.deleteSnapshot(id);
+	 assertRequestHasCommonProperties(server.takeRequest());
+	 Assert.assertFalse(result);
+      } finally {
+	 pbApi.close();
+	 server.shutdown();
+      }
+   }
+
+   @Test
+   public void testRollbackSnapshot() throws Exception {
+      MockWebServer server = mockWebServer();
+      server.enqueue(new MockResponse().setBody(payloadFromResource("/snapshot/snapshot-rollback.xml")));
+
+      ProfitBricksApi pbApi = api(server.getUrl(rootUrl));
+      SnapshotApi api = pbApi.snapshotApi();
+
+      String snapshotId = "qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh";
+      String storageId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";
+
+      String content = "<ws:rollbackSnapshot><request><snapshotId>" + snapshotId + "</snapshotId><storageId>" + storageId + "</storageId></request></ws:rollbackSnapshot>";
+      try {
+	 String result = api.rollbackSnapshot(Snapshot.Request.rollbackBuilder()
+		 .snapshotId(snapshotId)
+		 .storageId(storageId)
+		 .build());
+	 assertRequestHasCommonProperties(server.takeRequest(), content);
+	 assertNotNull(result);
+      } finally {
+	 pbApi.close();
+	 server.shutdown();
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandlerTest.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandlerTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandlerTest.java
new file mode 100644
index 0000000..38dfa1e
--- /dev/null
+++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandlerTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.profitbricks.http.parser.snapshot;
+
+import com.google.common.collect.Lists;
+import java.util.List;
+import org.jclouds.date.DateCodec;
+import org.jclouds.date.DateCodecFactory;
+import org.jclouds.http.functions.ParseSax;
+import org.jclouds.profitbricks.domain.Location;
+import org.jclouds.profitbricks.domain.OsType;
+import org.jclouds.profitbricks.domain.ProvisioningState;
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.jclouds.profitbricks.http.parser.BaseResponseHandlerTest;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "SnapshotListResponseHandlerTest")
+public class SnapshotListResponseHandlerTest extends BaseResponseHandlerTest<List<Snapshot>> {
+
+   @Override
+   protected ParseSax<List<Snapshot>> createParser() {
+      return factory.create(injector.getInstance(SnapshotListResponseHandler.class));
+   }
+
+   protected DateCodecFactory createDateParser() {
+      return injector.getInstance(DateCodecFactory.class);
+   }
+
+   @Test
+   public void testParseResponseFromGetSnapshot() {
+      ParseSax<List<Snapshot>> parser = createParser();
+
+      List<Snapshot> actual = parser.parse(payloadFromResource("/snapshot/snapshots.xml"));
+      assertNotNull(actual);
+
+      DateCodec dateParser = createDateParser().iso8601();
+
+      List<Snapshot> expected = Lists.newArrayList();
+
+      expected.add(Snapshot.builder()
+	      .id("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee")
+	      .description("description")
+	      .size(1024)
+	      .name("snapshot01")
+	      .state(ProvisioningState.AVAILABLE)
+	      .bootable(true)
+	      .osType(OsType.LINUX)
+	      .cpuHotPlug(true)
+	      .cpuHotUnPlug(true)
+	      .discVirtioHotPlug(true)
+	      .discVirtioHotUnPlug(true)
+	      .ramHotPlug(true)
+	      .ramHotUnPlug(true)
+	      .nicHotPlug(true)
+	      .nicHotUnPlug(true)
+	      .location(Location.US_LAS)
+	      .creationTime(dateParser.toDate("2015-01-26T07:09:23.138Z"))
+	      .lastModificationTime(dateParser.toDate("2015-01-26T07:09:23.138Z"))
+	      .build());
+
+      expected.add(Snapshot.builder()
+	      .id("qqqqqqqq-wwww-rrrr-tttt-yyyyyyyyyyyy")
+	      .description("description")
+	      .size(1024)
+	      .name("snapshot02")
+	      .state(ProvisioningState.AVAILABLE)
+	      .bootable(true)
+	      .osType(OsType.LINUX)
+	      .cpuHotPlug(true)
+	      .cpuHotUnPlug(true)
+	      .discVirtioHotPlug(true)
+	      .discVirtioHotUnPlug(true)
+	      .ramHotPlug(true)
+	      .ramHotUnPlug(true)
+	      .nicHotPlug(true)
+	      .nicHotUnPlug(true)
+	      .location(Location.US_LAS)
+	      .creationTime(dateParser.toDate("2015-01-26T07:09:23.138Z"))
+	      .lastModificationTime(dateParser.toDate("2015-01-26T07:09:23.138Z"))
+	      .build());
+
+      assertEquals(actual, expected);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandlerTest.java
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandlerTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandlerTest.java
new file mode 100644
index 0000000..9928e92
--- /dev/null
+++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandlerTest.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.jclouds.profitbricks.http.parser.snapshot;
+
+import org.jclouds.date.DateCodec;
+import org.jclouds.date.DateCodecFactory;
+import org.jclouds.http.functions.ParseSax;
+import org.jclouds.profitbricks.domain.Location;
+import org.jclouds.profitbricks.domain.OsType;
+import org.jclouds.profitbricks.domain.ProvisioningState;
+import org.jclouds.profitbricks.domain.Snapshot;
+import org.jclouds.profitbricks.http.parser.BaseResponseHandlerTest;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "ServerResponseHandlerTest")
+public class SnapshotResponseHandlerTest extends BaseResponseHandlerTest<Snapshot> {
+
+   @Override
+   protected ParseSax<Snapshot> createParser() {
+      return factory.create(injector.getInstance(SnapshotResponseHandler.class));
+   }
+
+   protected DateCodecFactory createDateParser() {
+      return injector.getInstance(DateCodecFactory.class);
+   }
+
+   @Test
+   public void testParseResponseFromGetSnapshot() {
+      ParseSax<Snapshot> parser = createParser();
+
+      Snapshot actual = parser.parse(payloadFromResource("/snapshot/snapshot.xml"));
+      assertNotNull(actual, "Parsed content returned null");
+
+      DateCodec dateParser = createDateParser().iso8601();
+
+      Snapshot expected = Snapshot.builder()
+	      .id("qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh")
+	      .description("description")
+	      .size(1024)
+	      .name("snapshot01")
+	      .state(ProvisioningState.AVAILABLE)
+	      .bootable(true)
+	      .osType(OsType.LINUX)
+	      .cpuHotPlug(true)
+	      .cpuHotUnPlug(true)
+	      .discVirtioHotPlug(true)
+	      .discVirtioHotUnPlug(true)
+	      .ramHotPlug(true)
+	      .ramHotUnPlug(true)
+	      .nicHotPlug(true)
+	      .nicHotUnPlug(true)
+	      .location(Location.US_LAS)
+	      .creationTime(dateParser.toDate("2015-01-26T07:09:23.138Z"))
+	      .lastModificationTime(dateParser.toDate("2015-01-26T07:09:23.138Z"))
+	      .build();
+
+      assertEquals(actual, expected);
+
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/resources/snapshot/snapshot-create.xml
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/resources/snapshot/snapshot-create.xml b/providers/profitbricks/src/test/resources/snapshot/snapshot-create.xml
new file mode 100644
index 0000000..06a537d
--- /dev/null
+++ b/providers/profitbricks/src/test/resources/snapshot/snapshot-create.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
+    <S:Body>
+        <ns2:createSnapshotReturn xmlns:ns2="http://ws.api.profitbricks.com/">
+            <return>
+                <requestId>12345678</requestId>
+                <snapshotId>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</snapshotId>
+            </return>
+        </ns2:createSnapshotReturn>
+    </S:Body>
+</S:Envelope>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/resources/snapshot/snapshot-delete.xml
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/resources/snapshot/snapshot-delete.xml b/providers/profitbricks/src/test/resources/snapshot/snapshot-delete.xml
new file mode 100644
index 0000000..45bf1a3
--- /dev/null
+++ b/providers/profitbricks/src/test/resources/snapshot/snapshot-delete.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
+    <S:Body>
+        <ns2:deleteSnapshotResponse xmlns:ns2="http://ws.api.profitbricks.com/">
+            <return>
+                <requestId>123456789</requestId>
+            </return>
+        </ns2:deleteSnapshotResponse>
+    </S:Body>
+</S:Envelope>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/resources/snapshot/snapshot-rollback.xml
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/resources/snapshot/snapshot-rollback.xml b/providers/profitbricks/src/test/resources/snapshot/snapshot-rollback.xml
new file mode 100644
index 0000000..661ce21
--- /dev/null
+++ b/providers/profitbricks/src/test/resources/snapshot/snapshot-rollback.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
+    <S:Body>
+        <ns2:rollbackSnapshotResponse xmlns:ns2="http://ws.api.profitbricks.com/">
+            <return>
+                <requestId>1234567890</requestId>
+                <dataCenterId>qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh</dataCenterId>
+                <dataCenterVersion>1</dataCenterVersion>
+            </return>
+        </ns2:rollbackSnapshotResponse>
+    </S:Body>
+</S:Envelope>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/resources/snapshot/snapshot-state-inprocess.xml
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/resources/snapshot/snapshot-state-inprocess.xml b/providers/profitbricks/src/test/resources/snapshot/snapshot-state-inprocess.xml
new file mode 100644
index 0000000..9f8acff
--- /dev/null
+++ b/providers/profitbricks/src/test/resources/snapshot/snapshot-state-inprocess.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
+    <S:Body>
+        <ns2:getSnapshotResponse xmlns:ns2="http://ws.api.profitbricks.com/">
+            <return>
+                <snapshotId>qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh</snapshotId>
+                <description>description</description>
+                <snapshotSize>1024</snapshotSize>
+                <snapshotName>snapshot01</snapshotName>
+                <provisioningState>INPROCESS</provisioningState>
+                <bootable>true</bootable>
+                <osType>LINUX</osType>
+                <cpuHotPlug>true</cpuHotPlug>
+                <cpuHotUnPlug>true</cpuHotUnPlug>
+                <discVirtioHotPlug>true</discVirtioHotPlug>
+                <discVirtioHotUnPlug>true</discVirtioHotUnPlug>
+                <ramHotPlug>true</ramHotPlug>
+                <ramHotUnPlug>true</ramHotUnPlug>
+                <nicHotPlug>true</nicHotPlug>
+                <nicHotUnPlug>true</nicHotUnPlug>
+                <creationTimestamp>2015-01-26T07:09:23.138Z</creationTimestamp>
+                <modificationTimestamp>2015-01-26T07:09:23.138Z</modificationTimestamp>
+                <location>us/las</location>
+            </return>
+        </ns2:getSnapshotResponse>
+    </S:Body>
+</S:Envelope>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/resources/snapshot/snapshot-update.xml
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/resources/snapshot/snapshot-update.xml b/providers/profitbricks/src/test/resources/snapshot/snapshot-update.xml
new file mode 100644
index 0000000..028cce0
--- /dev/null
+++ b/providers/profitbricks/src/test/resources/snapshot/snapshot-update.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
+    <S:Body>
+        <ns2:updateSnapshotResponse xmlns:ns2="http://ws.api.profitbricks.com/">
+            <return>
+                <requestId>12345678</requestId>
+            </return>
+        </ns2:updateSnapshotResponse>
+    </S:Body>
+</S:Envelope>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/resources/snapshot/snapshot.xml
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/resources/snapshot/snapshot.xml b/providers/profitbricks/src/test/resources/snapshot/snapshot.xml
new file mode 100644
index 0000000..d406be1
--- /dev/null
+++ b/providers/profitbricks/src/test/resources/snapshot/snapshot.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
+    <S:Body>
+        <ns2:getSnapshotResponse xmlns:ns2="http://ws.api.profitbricks.com/">
+            <return>
+                <snapshotId>qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh</snapshotId>
+                <description>description</description>
+                <snapshotSize>1024</snapshotSize>
+                <snapshotName>snapshot01</snapshotName>
+                <provisioningState>AVAILABLE</provisioningState>
+                <bootable>true</bootable>
+                <osType>LINUX</osType>
+                <cpuHotPlug>true</cpuHotPlug>
+                <cpuHotUnPlug>true</cpuHotUnPlug>
+                <discVirtioHotPlug>true</discVirtioHotPlug>
+                <discVirtioHotUnPlug>true</discVirtioHotUnPlug>
+                <ramHotPlug>true</ramHotPlug>
+                <ramHotUnPlug>true</ramHotUnPlug>
+                <nicHotPlug>true</nicHotPlug>
+                <nicHotUnPlug>true</nicHotUnPlug>
+                <creationTimestamp>2015-01-26T07:09:23.138Z</creationTimestamp>
+                <modificationTimestamp>2015-01-26T07:09:23.138Z</modificationTimestamp>
+                <location>us/las</location>
+            </return>
+        </ns2:getSnapshotResponse>
+    </S:Body>
+</S:Envelope>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/36d499b4/providers/profitbricks/src/test/resources/snapshot/snapshots.xml
----------------------------------------------------------------------
diff --git a/providers/profitbricks/src/test/resources/snapshot/snapshots.xml b/providers/profitbricks/src/test/resources/snapshot/snapshots.xml
new file mode 100644
index 0000000..d59826a
--- /dev/null
+++ b/providers/profitbricks/src/test/resources/snapshot/snapshots.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
+    <S:Body>
+        <ns2:getAllSnapshotsResponse xmlns:ns2="http://ws.api.profitbricks.com/">
+            <return>
+            <snapshotId>aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee</snapshotId>
+            <description>description</description>
+            <snapshotSize>1024</snapshotSize>
+            <snapshotName>snapshot01</snapshotName>
+            <provisioningState>AVAILABLE</provisioningState>
+            <bootable>true</bootable>
+            <osType>LINUX</osType>
+            <cpuHotPlug>true</cpuHotPlug>
+            <cpuHotUnPlug>true</cpuHotUnPlug>
+            <discVirtioHotPlug>true</discVirtioHotPlug>
+            <discVirtioHotUnPlug>true</discVirtioHotUnPlug>
+            <ramHotPlug>true</ramHotPlug>
+            <ramHotUnPlug>true</ramHotUnPlug>
+            <nicHotPlug>true</nicHotPlug>
+            <nicHotUnPlug>true</nicHotUnPlug>
+            <creationTimestamp>2015-01-26T07:09:23.138Z</creationTimestamp>
+            <modificationTimestamp>2015-01-26T07:09:23.138Z</modificationTimestamp>
+            <location>us/las</location>
+        </return>
+            <return>
+                <snapshotId>qqqqqqqq-wwww-rrrr-tttt-yyyyyyyyyyyy</snapshotId>
+                <description>description</description>
+                <snapshotSize>1024</snapshotSize>
+                <snapshotName>snapshot02</snapshotName>
+                <provisioningState>AVAILABLE</provisioningState>
+                <bootable>true</bootable>
+                <osType>LINUX</osType>
+                <cpuHotPlug>true</cpuHotPlug>
+                <cpuHotUnPlug>true</cpuHotUnPlug>
+                <discVirtioHotPlug>true</discVirtioHotPlug>
+                <discVirtioHotUnPlug>true</discVirtioHotUnPlug>
+                <ramHotPlug>true</ramHotPlug>
+                <ramHotUnPlug>true</ramHotUnPlug>
+                <nicHotPlug>true</nicHotPlug>
+                <nicHotUnPlug>true</nicHotUnPlug>
+                <creationTimestamp>2015-01-26T07:09:23.138Z</creationTimestamp>
+                <modificationTimestamp>2015-01-26T07:09:23.138Z</modificationTimestamp>
+                <location>us/las</location>
+            </return>
+        </ns2:getAllSnapshotsResponse>
+    </S:Body>
+</S:Envelope>