Merge pull request #1187 from dralves/gce-images

gce - images api
This commit is contained in:
Adrian Cole 2013-01-16 18:20:19 -08:00
commit 155bdb6d73
18 changed files with 1283 additions and 0 deletions

View File

@ -21,6 +21,7 @@ package org.jclouds.googlecompute;
import com.google.common.annotations.Beta;
import org.jclouds.googlecompute.features.DiskApi;
import org.jclouds.googlecompute.features.FirewallApi;
import org.jclouds.googlecompute.features.ImageApi;
import org.jclouds.googlecompute.features.KernelApi;
import org.jclouds.googlecompute.features.MachineTypeApi;
import org.jclouds.googlecompute.features.NetworkApi;
@ -61,6 +62,15 @@ public interface GoogleComputeApi {
@Path("/projects/{project}")
FirewallApi getFirewallApiForProject(@PathParam("project") String projectName);
/**
* Provides synchronous access to Image features
*
* @param projectName the name of the project
*/
@Delegate
@Path("/projects/{project}")
ImageApi getImageApiForProject(@PathParam("project") String projectName);
/**
* Provides synchronous access to Kernel features
*

View File

@ -21,6 +21,7 @@ package org.jclouds.googlecompute;
import com.google.common.annotations.Beta;
import org.jclouds.googlecompute.features.DiskAsyncApi;
import org.jclouds.googlecompute.features.FirewallAsyncApi;
import org.jclouds.googlecompute.features.ImageAsyncApi;
import org.jclouds.googlecompute.features.KernelAsyncApi;
import org.jclouds.googlecompute.features.MachineTypeAsyncApi;
import org.jclouds.googlecompute.features.NetworkAsyncApi;
@ -61,11 +62,22 @@ public interface GoogleComputeAsyncApi {
@Path("/projects/{project}")
FirewallAsyncApi getFirewallApiForProject(@PathParam("project") String projectName);
/**
* Provides asynchronous access to Image features
*
* @param projectName the name of the project
*/
@Delegate
@Path("/projects/{project}")
ImageAsyncApi getImageApiForProject(@PathParam("project") String projectName);
/**
* Provides asynchronous access to Kernel features
*
* @param projectName the name of the project
*/
@Delegate
@Path("/projects/{project}")
KernelAsyncApi getKernelApiForProject(@PathParam("project") String projectName);
/**

View File

@ -34,6 +34,8 @@ import org.jclouds.googlecompute.features.DiskApi;
import org.jclouds.googlecompute.features.DiskAsyncApi;
import org.jclouds.googlecompute.features.FirewallApi;
import org.jclouds.googlecompute.features.FirewallAsyncApi;
import org.jclouds.googlecompute.features.ImageApi;
import org.jclouds.googlecompute.features.ImageAsyncApi;
import org.jclouds.googlecompute.features.KernelApi;
import org.jclouds.googlecompute.features.KernelAsyncApi;
import org.jclouds.googlecompute.features.MachineTypeApi;
@ -76,6 +78,7 @@ public class GoogleComputeRestClientModule extends RestClientModule<GoogleComput
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>>builder()
.put(DiskApi.class, DiskAsyncApi.class)
.put(FirewallApi.class, FirewallAsyncApi.class)
.put(ImageApi.class, ImageAsyncApi.class)
.put(KernelApi.class, KernelAsyncApi.class)
.put(MachineTypeApi.class, MachineTypeAsyncApi.class)
.put(NetworkApi.class, NetworkAsyncApi.class)

View File

@ -0,0 +1,291 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.googlecompute.domain;
import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import java.beans.ConstructorProperties;
import java.net.URI;
import java.util.Date;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import static com.google.common.base.Optional.fromNullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Represents a disk image to use on an instance.
*
* @author David Alves
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/images"/>
*/
@Beta
public final class Image extends Resource {
private final String sourceType;
private final Optional<URI> preferredKernel;
private final RawDisk rawDisk;
@ConstructorProperties({
"id", "creationTimestamp", "selfLink", "name", "description", "sourceType", "preferredKernel",
"rawDisk"
})
protected Image(String id, Date creationTimestamp, URI selfLink, String name, String description,
String sourceType, URI preferredKernel, RawDisk rawDisk) {
super(Kind.IMAGE, checkNotNull(id, "id of %s", name), fromNullable(creationTimestamp),
checkNotNull(selfLink, "selfLink of %s", name), checkNotNull(name, "name"), fromNullable(description));
this.sourceType = checkNotNull(sourceType, "sourceType of %s", name);
this.preferredKernel = fromNullable(preferredKernel);
this.rawDisk = checkNotNull(rawDisk, "rawDisk of %s", name); ;
}
/**
* @return must be RAW; provided by the client when the disk image is created.
*/
public String getSourceType() {
return sourceType;
}
/**
* @return An optional URL of the preferred kernel for use with this disk image.
*/
public Optional<URI> getPreferredKernel() {
return preferredKernel;
}
/**
* @return the raw disk image parameters.
*/
public RawDisk getRawDisk() {
return rawDisk;
}
/**
* {@inheritDoc}
*/
protected Objects.ToStringHelper string() {
return super.string()
.omitNullValues()
.add("sourceType", sourceType)
.add("preferredKernel", preferredKernel.orNull())
.add("rawDisk", rawDisk);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return string().toString();
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return new Builder().fromImage(this);
}
public static final class Builder extends Resource.Builder<Builder> {
private String sourceType;
private URI preferredKernel;
private RawDisk rawDisk;
/**
* @see Image#getSourceType()
*/
public Builder sourceType(String sourceType) {
this.sourceType = checkNotNull(sourceType, "sourceType");
return this;
}
/**
* @see Image#getPreferredKernel()
*/
public Builder preferredKernel(URI preferredKernel) {
this.preferredKernel = preferredKernel;
return this;
}
/**
* @see Image#getRawDisk()
*/
public Builder rawDisk(RawDisk rawDisk) {
this.rawDisk = checkNotNull(rawDisk);
return this;
}
@Override
protected Builder self() {
return this;
}
public Image build() {
return new Image(super.id, super.creationTimestamp, super.selfLink, super.name,
super.description, sourceType, preferredKernel, rawDisk);
}
public Builder fromImage(Image in) {
return super.fromResource(in)
.sourceType(in.getSourceType())
.preferredKernel(in.getPreferredKernel().orNull())
.rawDisk(in.getRawDisk());
}
}
/**
* A raw disk image, usually the base for an image.
*
* @author David Alves
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/images"/>
*/
public static class RawDisk {
private final String source;
private final String containerType;
private final Optional<String> sha1Checksum;
@ConstructorProperties({
"source", "containerType", "sha1Checksum"
})
private RawDisk(String source, String containerType, String sha1Checksum) {
this.source = checkNotNull(source, "source");
this.containerType = checkNotNull(containerType, "containerType");
this.sha1Checksum = fromNullable(sha1Checksum);
}
/**
* @return the full Google Cloud Storage URL where the disk image is stored; provided by the client when the disk
* image is created.
*/
public String getSource() {
return source;
}
/**
* @return the format used to encode and transmit the block device.
*/
public String getContainerType() {
return containerType;
}
/**
* @return an optional SHA1 checksum of the disk image before unpackaging; provided by the client when the disk
* image is created.
*/
public Optional<String> getSha1Checksum() {
return sha1Checksum;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return Objects.hashCode(source, containerType, sha1Checksum);
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
RawDisk that = RawDisk.class.cast(obj);
return equal(this.source, that.source)
&& equal(this.containerType, that.containerType)
&& equal(this.sha1Checksum, that.sha1Checksum);
}
/**
* {@inheritDoc}
*/
protected Objects.ToStringHelper string() {
return toStringHelper(this)
.omitNullValues()
.add("source", source)
.add("containerType", containerType)
.add("sha1Checksum", sha1Checksum.orNull());
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return string().toString();
}
public static Builder builder() {
return new Builder();
}
public Builder toBuilder() {
return builder().fromImageRawDisk(this);
}
public static class Builder {
private String source;
private String containerType;
private String sha1Checksum;
/**
* @see org.jclouds.googlecompute.domain.Image.RawDisk#getSource()
*/
public Builder source(String source) {
this.source = checkNotNull(source);
return this;
}
/**
* @see org.jclouds.googlecompute.domain.Image.RawDisk#getContainerType()
*/
public Builder containerType(String containerType) {
this.containerType = checkNotNull(containerType);
return this;
}
/**
* @see org.jclouds.googlecompute.domain.Image.RawDisk#getSha1Checksum()
*/
public Builder sha1Checksum(String sha1Checksum) {
this.sha1Checksum = sha1Checksum;
return this;
}
public RawDisk build() {
return new RawDisk(source, containerType, sha1Checksum);
}
public Builder fromImageRawDisk(RawDisk rawDisk) {
return new Builder().source(rawDisk.getSource())
.containerType(rawDisk.getContainerType())
.sha1Checksum(rawDisk.getSha1Checksum().orNull());
}
}
}
}

View File

@ -0,0 +1,93 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.googlecompute.features;
import org.jclouds.collect.PagedIterable;
import org.jclouds.googlecompute.domain.Image;
import org.jclouds.googlecompute.domain.ListPage;
import org.jclouds.googlecompute.domain.Operation;
import org.jclouds.googlecompute.options.ListOptions;
import org.jclouds.javax.annotation.Nullable;
/**
* Provides synchronous access to Images via their REST API.
* <p/>
*
* @author David Alves
* @see ImageAsyncApi
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/images"/>
*/
public interface ImageApi {
/**
* Returns the specified image resource.
*
* @param imageName name of the image resource to return.
* @return an Image resource
*/
Image get(String imageName);
/**
* @see ImageApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
*/
public ListPage<Image> listFirstPage();
/**
* @see ImageApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
*/
public ListPage<Image> listAtMarker(@Nullable String marker);
/**
* Deletes the specified image resource.
*
* @param imageName name of the image resource to delete.
* @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. If the image did not exist the result is null.
*/
Operation delete(String imageName);
/**
* Retrieves the list of image resources available to the specified project.
* By default the list as a maximum size of 100, if no options are provided or ListOptions#getMaxResults() has not
* been set.
*
*
* @param marker marks the beginning of the next list page
* @param listOptions listing options
* @return a page of the list
* @see ListOptions
* @see org.jclouds.googlecompute.domain.ListPage
*/
ListPage<Image> listAtMarker(String marker, @Nullable ListOptions listOptions);
/**
* @see ImageApi#list(org.jclouds.googlecompute.options.ListOptions)
*/
public PagedIterable<Image> list();
/**
* A paged version of ImageApi#list()
*
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
* @see PagedIterable
* @see ImageApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
*/
PagedIterable<Image> list(@Nullable ListOptions listOptions);
}

View File

@ -0,0 +1,139 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.googlecompute.features;
import com.google.common.util.concurrent.ListenableFuture;
import org.jclouds.collect.PagedIterable;
import org.jclouds.googlecompute.domain.Image;
import org.jclouds.googlecompute.domain.ListPage;
import org.jclouds.googlecompute.domain.Operation;
import org.jclouds.googlecompute.functions.internal.ParseImages;
import org.jclouds.googlecompute.options.ListOptions;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.oauth.v2.config.OAuthScopes;
import org.jclouds.oauth.v2.filters.OAuthAuthenticator;
import org.jclouds.rest.annotations.Fallback;
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 javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import static org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
import static org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
import static org.jclouds.Fallbacks.NullOnNotFoundOr404;
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_READONLY_SCOPE;
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_SCOPE;
/**
* Provides asynchronous access to Images via their REST API.
*
* @author David Alves
* @see ImageApi
*/
@SkipEncoding({'/', '='})
@RequestFilters(OAuthAuthenticator.class)
public interface ImageAsyncApi {
/**
* @see ImageApi#get(String)
*/
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/images/{image}")
@OAuthScopes(COMPUTE_READONLY_SCOPE)
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Image> get(@PathParam("image") String imageName);
/**
* @see ImageApi#delete(String)
*/
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
@Path("/images/{image}")
@OAuthScopes(COMPUTE_SCOPE)
@Fallback(NullOnNotFoundOr404.class)
ListenableFuture<Operation> delete(@PathParam("image") String imageName);
/**
* @see ImageApi#listFirstPage()
*/
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/images")
@OAuthScopes(COMPUTE_READONLY_SCOPE)
@ResponseParser(ParseImages.class)
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
ListenableFuture<ListPage<Image>> listFirstPage();
/**
* @see ImageApi#listAtMarker(String)
*/
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/images")
@OAuthScopes(COMPUTE_READONLY_SCOPE)
@ResponseParser(ParseImages.class)
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
ListenableFuture<ListPage<Image>> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
/**
* @see ImageApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
*/
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/images")
@OAuthScopes(COMPUTE_READONLY_SCOPE)
@ResponseParser(ParseImages.class)
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
ListenableFuture<ListPage<Image>> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
ListOptions options);
/**
* @see ImageApi#listAtMarker(String)
*/
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/images")
@OAuthScopes(COMPUTE_READONLY_SCOPE)
@ResponseParser(ParseImages.class)
@Transform(ParseImages.ToPagedIterable.class)
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
ListenableFuture<? extends PagedIterable<Image>> list();
/**
* @see ImageApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
*/
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Path("/images")
@OAuthScopes(COMPUTE_READONLY_SCOPE)
@ResponseParser(ParseImages.class)
@Transform(ParseImages.ToPagedIterable.class)
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
ListenableFuture<? extends PagedIterable<Image>> list(ListOptions options);
}

View File

@ -0,0 +1,67 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.googlecompute.functions.internal;
import com.google.common.base.Function;
import com.google.inject.TypeLiteral;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.googlecompute.GoogleComputeApi;
import org.jclouds.googlecompute.domain.Image;
import org.jclouds.googlecompute.domain.ListPage;
import org.jclouds.googlecompute.options.ListOptions;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.json.Json;
import javax.inject.Inject;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* @author David Alves
*/
public class ParseImages extends ParseJson<ListPage<Image>> {
@Inject
public ParseImages(Json json) {
super(json, new TypeLiteral<ListPage<Image>>() {});
}
public static class ToPagedIterable extends BaseToPagedIterable<Image, ToPagedIterable> {
private final GoogleComputeApi api;
@Inject
protected ToPagedIterable(GoogleComputeApi api) {
this.api = checkNotNull(api, "api");
}
@Override
protected Function<Object, IterableWithMarker<Image>> fetchNextPage(final String projectName,
final ListOptions options) {
return new Function<Object, IterableWithMarker<Image>>() {
@Override
public IterableWithMarker<Image> apply(Object input) {
return api.getImageApiForProject(projectName).listAtMarker(input.toString(), options);
}
};
}
}
}

View File

@ -0,0 +1,119 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.googlecompute;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.googlecompute.domain.Image;
import org.jclouds.googlecompute.features.ImageApi;
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
import org.jclouds.googlecompute.options.ListOptions;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_READONLY_SCOPE;
import static org.testng.Assert.assertSame;
/**
* A test specifically for the paging system. The code used is common to all list() methods so we're using Images
* but it could be anything else.
*
* @author David Alves
*/
@Test(groups = "unit")
public class PageSystemExpectTest extends BaseGoogleComputeApiExpectTest {
public void testGetSinglePage() {
HttpRequest list = HttpRequest
.builder()
.method("GET")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/myproject/images")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/image_list_single_page.json")).build();
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
TOKEN_RESPONSE, list, operationResponse).getImageApiForProject("myproject");
PagedIterable<Image> images = imageApi.list();
// expect one page
assertSame(images.size(), 1);
// with three images
assertSame(images.concat().size(), 3);
}
public void testGetMultiplePages() {
HttpRequest list1 = HttpRequest
.builder()
.method("GET")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/myproject/images?maxResults=3")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpRequest list2 = HttpRequest
.builder()
.method("GET")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/myproject/images?pageToken" +
"=CgVJTUFHRRIbZ29vZ2xlLmNlbnRvcy02LTItdjIwMTIwNjIx&maxResults=3")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpRequest list3 = HttpRequest
.builder()
.method("GET")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/myproject/images?pageToken" +
"=CgVJTUFHRRIbZ29vZ2xlLmdjZWwtMTAtMDQtdjIwMTIxMTA2&maxResults=3")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpResponse list1response = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/image_list_multiple_page_1.json")).build();
HttpResponse list2Response = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/image_list_multiple_page_2.json")).build();
HttpResponse list3Response = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/image_list_single_page.json")).build();
ImageApi imageApi = orderedRequestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
TOKEN_RESPONSE, list1, list1response, list2, list2Response, list3, list3Response)
.getImageApiForProject("myproject");
PagedIterable<Image> images = imageApi.list(new ListOptions.Builder().maxResults(3));
int imageCounter = 0;
for (IterableWithMarker<Image> page : images) {
for (Image image : page) {
imageCounter++;
}
}
assertSame(imageCounter, 9);
}
}

View File

@ -0,0 +1,149 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.googlecompute.features;
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
import org.jclouds.googlecompute.parse.ParseImageListTest;
import org.jclouds.googlecompute.parse.ParseImageTest;
import org.jclouds.googlecompute.parse.ParseOperationTest;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.testng.annotations.Test;
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_READONLY_SCOPE;
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_SCOPE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.AssertJUnit.assertNull;
/**
* @author David Alves
*/
@Test(groups = "unit")
public class ImageApiExpectTest extends BaseGoogleComputeApiExpectTest {
public void testGetImageResponseIs2xx() throws Exception {
HttpRequest get = HttpRequest
.builder()
.method("GET")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/google/images/centos-6-2-v20120326")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/image_get.json")).build();
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
TOKEN_RESPONSE, get, operationResponse).getImageApiForProject("google");
assertEquals(imageApi.get("centos-6-2-v20120326"),
new ParseImageTest().expected());
}
public void testGetImageResponseIs4xx() throws Exception {
HttpRequest get = HttpRequest
.builder()
.method("GET")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/google/images/centos-6-2-v20120326")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
TOKEN_RESPONSE, get, operationResponse).getImageApiForProject("google");
assertNull(imageApi.get("centos-6-2-v20120326"));
}
public void testDeleteImageResponseIs2xx() {
HttpRequest delete = HttpRequest
.builder()
.method("DELETE")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/myproject/images/centos-6-2-v20120326")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/operation.json")).build();
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
TOKEN_RESPONSE, delete, deleteResponse).getImageApiForProject("myproject");
assertEquals(imageApi.delete("centos-6-2-v20120326"),
new ParseOperationTest().expected());
}
public void testDeleteImageResponseIs4xx() {
HttpRequest delete = HttpRequest
.builder()
.method("DELETE")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/myproject/images/centos-6-2-v20120326")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
TOKEN_RESPONSE, delete, deleteResponse).getImageApiForProject("myproject");
assertNull(imageApi.delete("centos-6-2-v20120326"));
}
public void testListImagesResponseIs2xx() {
HttpRequest list = HttpRequest
.builder()
.method("GET")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/myproject/images")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/image_list.json")).build();
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
TOKEN_RESPONSE, list, operationResponse).getImageApiForProject("myproject");
assertEquals(imageApi.listFirstPage().toString(),
new ParseImageListTest().expected().toString());
}
public void testListImagesResponseIs4xx() {
HttpRequest list = HttpRequest
.builder()
.method("GET")
.endpoint("https://www.googleapis" +
".com/compute/v1beta13/projects/myproject/images")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + TOKEN).build();
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
TOKEN_RESPONSE, list, operationResponse).getImageApiForProject("myproject");
assertTrue(imageApi.list().concat().isEmpty());
}
}

View File

@ -0,0 +1,81 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.googlecompute.features;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.jclouds.collect.IterableWithMarker;
import org.jclouds.collect.PagedIterable;
import org.jclouds.googlecompute.domain.Image;
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiLiveTest;
import org.jclouds.googlecompute.options.ListOptions;
import org.testng.annotations.Test;
import java.util.Iterator;
import java.util.List;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
/**
* TODO figure out how to test insert and delete as this requires an image .tar.gz to be present in GCS
*
* @author David Alves
*/
public class ImageApiLiveTest extends BaseGoogleComputeApiLiveTest {
private Image image;
private ImageApi api() {
return context.getApi().getImageApiForProject("google");
}
@Test(groups = "live")
public void testListImage() {
PagedIterable<Image> images = api().list(new ListOptions.Builder().maxResults(1));
Iterator<IterableWithMarker<Image>> pageIterator = images.iterator();
assertTrue(pageIterator.hasNext());
IterableWithMarker<Image> singlePageIterator = pageIterator.next();
List<Image> imageAsList = Lists.newArrayList(singlePageIterator);
assertSame(imageAsList.size(), 1);
this.image = Iterables.getOnlyElement(imageAsList);
}
@Test(groups = "live", dependsOnMethods = "testListImage")
public void testGetImage() {
Image image = api().get(this.image.getName());
assertNotNull(image);
assertImageEquals(image, this.image);
}
private void assertImageEquals(Image result, Image expected) {
assertEquals(result.getName(), expected.getName());
}
}

View File

@ -0,0 +1,72 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.googlecompute.parse;
import com.google.common.collect.ImmutableSet;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.googlecompute.domain.Image;
import org.jclouds.googlecompute.domain.ListPage;
import org.jclouds.googlecompute.domain.Resource;
import org.jclouds.googlecompute.internal.BaseGoogleComputeParseTest;
import org.testng.annotations.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import java.net.URI;
/**
* @author David Alves
*/
@Test(groups = "unit")
public class ParseImageListTest extends BaseGoogleComputeParseTest<ListPage<Image>> {
@Override
public String resource() {
return "/image_list.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public ListPage<Image> expected() {
return ListPage.<Image>builder()
.kind(Resource.Kind.IMAGE_LIST)
.id("projects/google/images")
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta13/projects/google/images"))
.items(ImmutableSet.of(Image.builder()
.id("12941197498378735318")
.creationTimestamp(new SimpleDateFormatDateService().iso8601DateParse("2012-07-16T22:16:13.468"))
.selfLink(URI.create("https://www.googleapis" +
".com/compute/v1beta13/projects/google/images/centos-6-2-v20120326"))
.name("centos-6-2-v20120326")
.description("DEPRECATED. CentOS 6.2 image; Created Mon, 26 Mar 2012 21:19:09 +0000")
.sourceType("RAW")
.preferredKernel(URI.create("https://www.googleapis" +
".com/compute/v1beta13/projects/google/kernels/gce-20120326"))
.rawDisk(
Image.RawDisk.builder()
.source("")
.containerType("TAR")
.build()
).build()
))
.build();
}
}

View File

@ -0,0 +1,62 @@
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.googlecompute.parse;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.googlecompute.domain.Image;
import org.jclouds.googlecompute.internal.BaseGoogleComputeParseTest;
import org.testng.annotations.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import java.net.URI;
/**
* @author David Alves
*/
@Test(groups = "unit")
public class ParseImageTest extends BaseGoogleComputeParseTest<Image> {
@Override
public String resource() {
return "/image_get.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public Image expected() {
return Image.builder()
.id("12941197498378735318")
.creationTimestamp(new SimpleDateFormatDateService().iso8601DateParse("2012-07-16T22:16:13.468"))
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta13/projects/google/images/centos-6-2" +
"-v20120326"))
.name("centos-6-2-v20120326")
.description("DEPRECATED. CentOS 6.2 image; Created Mon, 26 Mar 2012 21:19:09 +0000")
.sourceType("RAW")
.preferredKernel(URI.create("https://www.googleapis" +
".com/compute/v1beta13/projects/google/kernels/gce-20120326"))
.rawDisk(
Image.RawDisk.builder()
.source("")
.containerType("TAR")
.build()
).build();
}
}

View File

@ -0,0 +1,14 @@
{
"kind": "compute#image",
"id": "12941197498378735318",
"creationTimestamp": "2012-07-16T22:16:13.468",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/centos-6-2-v20120326",
"name": "centos-6-2-v20120326",
"description": "DEPRECATED. CentOS 6.2 image; Created Mon, 26 Mar 2012 21:19:09 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-20120326",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
}

View File

@ -0,0 +1 @@
{"sourceType":"RAW","rawDisk":{"source":"https://storage.googleapis.com/mybuket/myimage.image.tar.gz","containerType":"TAR"},"kind":"compute#image","name":"myimage"}

View File

@ -0,0 +1,21 @@
{
"kind": "compute#imageList",
"id": "projects/google/images",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images",
"items": [
{
"kind": "compute#image",
"id": "12941197498378735318",
"creationTimestamp": "2012-07-16T22:16:13.468",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/centos-6-2-v20120326",
"name": "centos-6-2-v20120326",
"description": "DEPRECATED. CentOS 6.2 image; Created Mon, 26 Mar 2012 21:19:09 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-20120326",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
}
]
}

View File

@ -0,0 +1,50 @@
{
"kind": "compute#imageList",
"id": "projects/google/images",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images",
"nextPageToken": "CgVJTUFHRRIbZ29vZ2xlLmNlbnRvcy02LTItdjIwMTIwNjIx",
"items": [
{
"kind": "compute#image",
"id": "12941197498378735318",
"creationTimestamp": "2012-07-16T15:16:13.468-07:00",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/centos-6-2-v20120326",
"name": "centos-6-2-v20120326",
"description": "DEPRECATED. CentOS 6.2 image; Created Mon, 26 Mar 2012 21:19:09 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-20120326",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
},
{
"kind": "compute#image",
"id": "12894486577628239762",
"creationTimestamp": "2012-05-21T13:15:37.215-07:00",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/centos-6-2-v20120503",
"name": "centos-6-2-v20120503",
"description": "CentOS 6.2; Created Wed, 09 May 2012 11:55:54 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-20120326",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
},
{
"kind": "compute#image",
"id": "12917726455664967299",
"creationTimestamp": "2012-06-18T11:05:30.664-07:00",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/centos-6-2-v20120611",
"name": "centos-6-2-v20120611",
"description": "CentOS 6.2; Created Mon, 11 Jun 2012 13:15:44 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-20120611",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
}
]
}

View File

@ -0,0 +1,50 @@
{
"kind": "compute#imageList",
"id": "projects/google/images",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images",
"nextPageToken": "CgVJTUFHRRIbZ29vZ2xlLmdjZWwtMTAtMDQtdjIwMTIxMTA2",
"items": [
{
"kind": "compute#image",
"id": "12920641029336858796",
"creationTimestamp": "2012-06-21T22:59:56.392-07:00",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/centos-6-2-v20120621",
"name": "centos-6-2-v20120621",
"description": "CentOS 6.2; Created Thu, 21 Jun 2012 14:22:21 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-20120621",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
},
{
"kind": "compute#image",
"id": "12994279803511049620",
"creationTimestamp": "2012-09-18T08:52:47.584-07:00",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/centos-6-v20120912",
"name": "centos-6-v20120912",
"description": "CentOS 6; Created Wed, 12 Sep 2012 00:00:00 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-v20120912",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
},
{
"kind": "compute#image",
"id": "13037720516378381209",
"creationTimestamp": "2012-11-09T11:40:41.079-08:00",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/centos-6-v20121106",
"name": "centos-6-v20121106",
"description": "SCSI-enabled CentOS 6; Created Tue, 06 Nov 2012 00:00:00 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-v20121106",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
}
]
}

View File

@ -0,0 +1,49 @@
{
"kind": "compute#imageList",
"id": "projects/google/images",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images",
"items": [
{
"kind": "compute#image",
"id": "13037722963789596520",
"creationTimestamp": "2012-11-09T11:43:28.749-08:00",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/gcel-10-04-v20121106",
"name": "gcel-10-04-v20121106",
"description": "SCSI-enabled GCEL 10.04 LTS; Created Tue, 06 Nov 2012 00:00:00 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-v20121106",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
},
{
"kind": "compute#image",
"id": "13037721421359523565",
"creationTimestamp": "2012-11-09T11:40:51.994-08:00",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/gcel-12-04-v20121106",
"name": "gcel-12-04-v20121106",
"description": "SCSI-enabled GCEL 12.04 LTS; Created Tue, 06 Nov 2012 00:00:00 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-v20121106",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
},
{
"kind": "compute#image",
"id": "12941198995845323366",
"creationTimestamp": "2012-07-16T15:18:50.405-07:00",
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/images/ubuntu-10-04-v20110728",
"name": "ubuntu-10-04-v20110728",
"description": "DEPRECATED. GCEL 10.04 LTS; Created Thu, 28 Jul 2011 16:45:51 +0000",
"sourceType": "RAW",
"preferredKernel": "https://www.googleapis.com/compute/v1beta13/projects/google/kernels/gce-20110728",
"rawDisk": {
"source": "",
"containerType": "TAR"
}
}
]
}