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

git commit: JCLOUDS-649: Added image creation from pd and made Image rawDisk Optional

Repository: jclouds-labs-google
Updated Branches:
  refs/heads/master c33b64c61 -> e81df9f75


JCLOUDS-649: Added image creation from pd and made Image rawDisk Optional<T>


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

Branch: refs/heads/master
Commit: e81df9f7572fd193d65a6d5709eb1a791381a04d
Parents: c33b64c
Author: Daniel Broudy <br...@google.com>
Authored: Wed Oct 15 10:33:27 2014 -0700
Committer: Daniel Broudy <br...@google.com>
Committed: Thu Oct 16 10:21:08 2014 -0700

----------------------------------------------------------------------
 .../googlecomputeengine/domain/Image.java       | 10 ++---
 .../googlecomputeengine/features/ImageApi.java  | 22 ++++++++++
 .../features/DiskApiLiveTest.java               |  2 -
 .../features/ImageApiExpectTest.java            | 44 +++++++++++++++++++
 .../features/ImageApiLiveTest.java              | 46 ++++++++++++++++++++
 .../BaseGoogleComputeEngineApiLiveTest.java     |  6 +++
 .../test/resources/image_insert_from_pd.json    |  1 +
 7 files changed, 124 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/e81df9f7/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Image.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Image.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Image.java
index 777b3e7..84c6975 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Image.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Image.java
@@ -39,7 +39,7 @@ import com.google.common.base.Optional;
 public final class Image extends Resource {
 
    private final String sourceType;
-   private final RawDisk rawDisk;
+   private final Optional<RawDisk> rawDisk;
    private final Optional<Deprecated> deprecated;
 
    @ConstructorProperties({
@@ -50,7 +50,7 @@ public final class Image extends Resource {
                    String sourceType, RawDisk rawDisk, Deprecated deprecated) {
       super(Kind.IMAGE, id, creationTimestamp, selfLink, name, description);
       this.sourceType = checkNotNull(sourceType, "sourceType of %s", name);
-      this.rawDisk = checkNotNull(rawDisk, "rawDisk of %s", name);
+      this.rawDisk = fromNullable(rawDisk);
       this.deprecated = fromNullable(deprecated);
    }
 
@@ -64,7 +64,7 @@ public final class Image extends Resource {
    /**
     * @return the raw disk image parameters.
     */
-   public RawDisk getRawDisk() {
+   public Optional<RawDisk> getRawDisk() {
       return rawDisk;
    }
 
@@ -146,7 +146,7 @@ public final class Image extends Resource {
       public Builder fromImage(Image in) {
          return super.fromResource(in)
                  .sourceType(in.getSourceType())
-                 .rawDisk(in.getRawDisk())
+                 .rawDisk(in.getRawDisk().orNull())
                  .deprecated(in.getDeprecated().orNull());
       }
 
@@ -188,7 +188,7 @@ public final class Image extends Resource {
       }
 
       /**
-       * @return an optional SHA1 checksum of the disk image before unpackaging; provided by the client when the disk
+       * @return an optional SHA1 checksum of the disk image before unpacking; provided by the client when the disk
        *         image is created.
        */
       public Optional<String> getSha1Checksum() {

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/e81df9f7/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
index d5755f2..f52d5cd 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
@@ -23,8 +23,10 @@ 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.Path;
 import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 
@@ -41,10 +43,13 @@ import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.oauth.v2.config.OAuthScopes;
 import org.jclouds.oauth.v2.filters.OAuthAuthenticationFilter;
 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.annotations.SkipEncoding;
 import org.jclouds.rest.annotations.Transform;
+import org.jclouds.rest.binders.BindToJsonPayload;
 
 /**
  * Provides access to Images via their REST API.
@@ -164,4 +169,21 @@ public interface ImageApi {
    @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
    PagedIterable<Image> list(ListOptions options);
 
+   /**
+    * Creates an image resource in the specified project from the provided persistent disk.
+    *
+    * @param imageName  the name of the created image
+    * @param sourceDisk fully qualified URL for the persistent disk to create the image from
+    * @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
+    *         you, and look for the status field.
+    */
+   @Named("Images:insert")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/global/images")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @MapBinder(BindToJsonPayload.class)
+   Operation createImageFromPD(@PayloadParam("name") String imageName, @PayloadParam("sourceDisk") String sourceDisk);
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/e81df9f7/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java
index bd26621..a1e197c 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java
@@ -23,7 +23,6 @@ import java.util.List;
 
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.googlecomputeengine.domain.Disk;
-import org.jclouds.googlecomputeengine.domain.Project;
 import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
 import org.jclouds.googlecomputeengine.options.ListOptions;
 import org.testng.annotations.Test;
@@ -43,7 +42,6 @@ public class DiskApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    @Test(groups = "live")
    public void testInsertDisk() {
-      Project project = api.getProjectApi().get(userProject.get());
       assertZoneOperationDoneSucessfully(api().createInZone(DISK_NAME, sizeGb, DEFAULT_ZONE_NAME), TIME_WAIT);
 
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/e81df9f7/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiExpectTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiExpectTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiExpectTest.java
index 1deb178..0665e1b 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiExpectTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiExpectTest.java
@@ -28,6 +28,7 @@ import org.jclouds.googlecomputeengine.parse.ParseImageTest;
 import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
 import org.jclouds.http.HttpRequest;
 import org.jclouds.http.HttpResponse;
+import org.jclouds.rest.ResourceNotFoundException;
 import org.testng.annotations.Test;
 
 @Test(groups = "unit")
@@ -156,4 +157,47 @@ public class ImageApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
 
       assertTrue(imageApi.list().concat().isEmpty());
    }
+
+   public void testCreateImageFromPdResponseIs2xx(){
+      HttpRequest createImage = HttpRequest
+            .builder()
+            .method("POST")
+            .endpoint("https://www.googleapis" +
+                    ".com/compute/v1/projects/myproject/global/images")
+            .addHeader("Accept", "application/json")
+            .addHeader("Authorization", "Bearer " + TOKEN)
+            .payload(payloadFromResource("/image_insert_from_pd.json"))
+            .build();
+
+      HttpResponse createImageResponse = HttpResponse.builder().statusCode(200)
+                                  .payload(payloadFromResource("/operation.json")).build();
+
+      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
+            TOKEN_RESPONSE, createImage, createImageResponse).getImageApiForProject("myproject");
+
+      assertEquals(imageApi.createImageFromPD("my-image", "https://www.googleapis.com/" +
+            "compute/v1/projects/myproject/zones/us-central1-a/disks/mydisk"),
+            new ParseOperationTest().expected());
+   }
+
+   @Test(expectedExceptions = ResourceNotFoundException.class)
+   public void testCreateImageFromPdResponseIs4xx() {
+      HttpRequest createImage = HttpRequest
+            .builder()
+            .method("POST")
+            .endpoint("https://www.googleapis" +
+                     ".com/compute/v1/projects/myproject/global/images")
+            .addHeader("Accept", "application/json")
+            .addHeader("Authorization", "Bearer " + TOKEN)
+            .payload(payloadFromResource("/image_insert_from_pd.json"))
+            .build();
+
+      HttpResponse createImageResponse = HttpResponse.builder().statusCode(404).build();
+
+      ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
+              TOKEN_RESPONSE, createImage, createImageResponse).getImageApiForProject("myproject");
+
+      imageApi.createImageFromPD("my-image", "https://www.googleapis.com/" +
+                  "compute/v1/projects/myproject/zones/us-central1-a/disks/mydisk");
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/e81df9f7/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java
index a4922b4..9c9ca55 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ImageApiLiveTest.java
@@ -21,11 +21,13 @@ import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
+import java.net.URI;
 import java.util.Iterator;
 import java.util.List;
 
 import org.jclouds.collect.IterableWithMarker;
 import org.jclouds.collect.PagedIterable;
+import org.jclouds.googlecomputeengine.domain.Disk;
 import org.jclouds.googlecomputeengine.domain.Image;
 import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
 import org.jclouds.googlecomputeengine.options.ListOptions;
@@ -36,12 +38,26 @@ import com.google.common.collect.Lists;
 
 public class ImageApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
+   public static final String DISK_NAME = "image-api-live-test-disk";
+   public static final int TIME_WAIT = 300;
+   public static final int sizeGb = 10;
+   public static final String IMAGE_NAME = "image-api-live-test-image";
+
    private Image image;
+   private URI diskURI;
 
    private ImageApi api() {
       return api.getImageApiForProject("centos-cloud");
    }
 
+   private ImageApi imageApi(){
+      return api.getImageApiForProject(userProject.get());
+   }
+
+   private DiskApi diskApi() {
+      return api.getDiskApiForProject(userProject.get());
+   }
+
    @Test(groups = "live")
    public void testListImage() {
 
@@ -70,5 +86,35 @@ public class ImageApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
       assertEquals(result.getName(), expected.getName());
    }
 
+   @Test(groups = "live")
+   public void testInsertDisk() {
+      assertZoneOperationDoneSucessfully(diskApi().createInZone(DISK_NAME, sizeGb, DEFAULT_ZONE_NAME), TIME_WAIT);
+      Disk disk = diskApi().getInZone(DEFAULT_ZONE_NAME, DISK_NAME);
+      diskURI = disk.getSelfLink();
+   }
+
+   @Test(groups = "live", dependsOnMethods = "testInsertDisk")
+   public void testCreateImageFromPD(){
+      assertGlobalOperationDoneSucessfully(imageApi().createImageFromPD(IMAGE_NAME, diskURI.toString()), TIME_WAIT);
+   }
+
+   @Test(groups = "live", dependsOnMethods = "testCreateImageFromPD")
+   public void testGetCreatedImage(){
+      Image image = imageApi().get(IMAGE_NAME);
+      assertImageEquals(image);
+   }
+
+   @Test(groups = "live", dependsOnMethods = "testGetCreatedImage")
+   public void testCleanup(){
+      assertGlobalOperationDoneSucessfully(imageApi().delete(IMAGE_NAME), TIME_WAIT);
+      assertZoneOperationDoneSucessfully(diskApi().deleteInZone(DEFAULT_ZONE_NAME, DISK_NAME), TIME_WAIT);
+   }
+
+   private void assertImageEquals(Image result) {
+      assertEquals(result.getName(), IMAGE_NAME);
+      assertEquals(result.getSourceType(), "RAW");
+      assertEquals(result.getSelfLink(), getImageUrl(userProject.get(), IMAGE_NAME) );
+   }
+
 }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/e81df9f7/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiLiveTest.java
index 2c018eb..836e6d0 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiLiveTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/internal/BaseGoogleComputeEngineApiLiveTest.java
@@ -58,6 +58,8 @@ public class BaseGoogleComputeEngineApiLiveTest extends BaseApiLiveTest<GoogleCo
    protected static final String GATEWAY_API_URL_SUFFIX = "/global/gateways/";
    protected static final String DEFAULT_GATEWAY_NAME = "default-internet-gateway";
 
+   protected static final String IMAGE_API_URL_SUFFIX = "/global/images/";
+
    protected static final String GOOGLE_PROJECT = "google";
 
    protected Supplier<String> userProject;
@@ -136,6 +138,10 @@ public class BaseGoogleComputeEngineApiLiveTest extends BaseApiLiveTest<GoogleCo
       return URI.create(API_URL_PREFIX + project + GATEWAY_API_URL_SUFFIX + gateway);
    }
 
+   protected URI getImageUrl(String project, String image){
+      return URI.create(API_URL_PREFIX + project + IMAGE_API_URL_SUFFIX + image);
+   }
+
    protected URI getDefaultMachineTypeUrl(String project) {
       return getMachineTypeUrl(project, DEFAULT_MACHINE_TYPE_NAME);
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/e81df9f7/google-compute-engine/src/test/resources/image_insert_from_pd.json
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/resources/image_insert_from_pd.json b/google-compute-engine/src/test/resources/image_insert_from_pd.json
new file mode 100644
index 0000000..0fa2a01
--- /dev/null
+++ b/google-compute-engine/src/test/resources/image_insert_from_pd.json
@@ -0,0 +1 @@
+{"name":"my-image","sourceDisk":"https://www.googleapis.com/compute/v1/projects/myproject/zones/us-central1-a/disks/mydisk"}
\ No newline at end of file