diff --git a/labs/google-compute/src/main/java/org/jclouds/googlecompute/GoogleComputeApi.java b/labs/google-compute/src/main/java/org/jclouds/googlecompute/GoogleComputeApi.java index 641ba34034..526ac8f440 100644 --- a/labs/google-compute/src/main/java/org/jclouds/googlecompute/GoogleComputeApi.java +++ b/labs/google-compute/src/main/java/org/jclouds/googlecompute/GoogleComputeApi.java @@ -19,6 +19,7 @@ package org.jclouds.googlecompute; import com.google.common.annotations.Beta; +import org.jclouds.googlecompute.features.DiskApi; import org.jclouds.googlecompute.features.OperationApi; import org.jclouds.googlecompute.features.ProjectApi; import org.jclouds.googlecompute.features.ZoneApi; @@ -26,6 +27,7 @@ import org.jclouds.rest.annotations.Delegate; import javax.ws.rs.Path; import javax.ws.rs.PathParam; + /** * Provides synchronous access to GoogleCompute. *

@@ -37,6 +39,15 @@ import javax.ws.rs.PathParam; @Beta public interface GoogleComputeApi { + /** + * Provides synchronous access to Disk features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + DiskApi getDiskApiForProject(@PathParam("project") String projectName); + /** * Provides synchronous access to Project features */ diff --git a/labs/google-compute/src/main/java/org/jclouds/googlecompute/GoogleComputeAsyncApi.java b/labs/google-compute/src/main/java/org/jclouds/googlecompute/GoogleComputeAsyncApi.java index 2cddad8bab..020fa9007b 100644 --- a/labs/google-compute/src/main/java/org/jclouds/googlecompute/GoogleComputeAsyncApi.java +++ b/labs/google-compute/src/main/java/org/jclouds/googlecompute/GoogleComputeAsyncApi.java @@ -19,6 +19,7 @@ package org.jclouds.googlecompute; import com.google.common.annotations.Beta; +import org.jclouds.googlecompute.features.DiskAsyncApi; import org.jclouds.googlecompute.features.OperationAsyncApi; import org.jclouds.googlecompute.features.ProjectAsyncApi; import org.jclouds.googlecompute.features.ZoneAsyncApi; @@ -37,6 +38,15 @@ import javax.ws.rs.PathParam; @Beta public interface GoogleComputeAsyncApi { + /** + * Provides asynchronous access to Disk features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + DiskAsyncApi getDiskApiForProject(@PathParam("project") String projectName); + /** * Provides asynchronous access to Project features */ diff --git a/labs/google-compute/src/main/java/org/jclouds/googlecompute/config/GoogleComputeRestClientModule.java b/labs/google-compute/src/main/java/org/jclouds/googlecompute/config/GoogleComputeRestClientModule.java index 851cc8627c..211ee5ee84 100644 --- a/labs/google-compute/src/main/java/org/jclouds/googlecompute/config/GoogleComputeRestClientModule.java +++ b/labs/google-compute/src/main/java/org/jclouds/googlecompute/config/GoogleComputeRestClientModule.java @@ -27,6 +27,8 @@ import com.google.inject.TypeLiteral; import org.jclouds.googlecompute.GoogleComputeApi; import org.jclouds.googlecompute.GoogleComputeAsyncApi; import org.jclouds.googlecompute.domain.Operation; +import org.jclouds.googlecompute.features.DiskApi; +import org.jclouds.googlecompute.features.DiskAsyncApi; import org.jclouds.googlecompute.features.OperationApi; import org.jclouds.googlecompute.features.OperationAsyncApi; import org.jclouds.googlecompute.features.ProjectApi; @@ -58,6 +60,7 @@ import static com.google.common.base.Preconditions.checkState; @ConfiguresRestClient public class GoogleComputeRestClientModule extends RestClientModule { public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class>builder() + .put(DiskApi.class, DiskAsyncApi.class) .put(OperationApi.class, OperationAsyncApi.class) .put(ProjectApi.class, ProjectAsyncApi.class) .put(ZoneApi.class, ZoneAsyncApi.class) diff --git a/labs/google-compute/src/main/java/org/jclouds/googlecompute/domain/Disk.java b/labs/google-compute/src/main/java/org/jclouds/googlecompute/domain/Disk.java new file mode 100644 index 0000000000..2d64536faa --- /dev/null +++ b/labs/google-compute/src/main/java/org/jclouds/googlecompute/domain/Disk.java @@ -0,0 +1,156 @@ +/* + * 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 java.beans.ConstructorProperties; +import java.net.URI; +import java.util.Date; + +import static com.google.common.base.Optional.fromNullable; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A persistent disk resource + * + * @author David Alves + * @see + */ +@Beta +public final class Disk extends Resource { + + private final Integer sizeGb; + private final URI zone; + private final String status; + + @ConstructorProperties({ + "id", "creationTimestamp", "selfLink", "name", "description", "sizeGb", "zone", + "status" + }) + private Disk(String id, Date creationTimestamp, URI selfLink, String name, String description, + Integer sizeGb, URI zone, String status) { + super(Kind.DISK, checkNotNull(id, "id of %s", name), fromNullable(creationTimestamp), checkNotNull(selfLink, + "selfLink of %s", name), checkNotNull(name, "name"), fromNullable(description)); + this.sizeGb = checkNotNull(sizeGb, "sizeGb of %s", name); + this.zone = checkNotNull(zone, "zone of %s", name); + this.status = checkNotNull(status, "status of %s", name); + } + + /** + * @return size of the persistent disk, specified in GB. + */ + public int getSizeGb() { + return sizeGb; + } + + /** + * @return URL for the zone where the persistent disk resides. + */ + public URI getZone() { + return zone; + } + + /** + * @return the status of disk creation. + */ + public String getStatus() { + return status; + } + + /** + * {@inheritDoc} + */ + protected Objects.ToStringHelper string() { + return super.string() + .omitNullValues() + .add("sizeGb", sizeGb) + .add("zone", zone) + .add("status", status); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return string().toString(); + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().fromDisk(this); + } + + public static final class Builder extends Resource.Builder { + + private Integer sizeGb; + private URI zone;; + private String status; + + /** + * @see Disk#getSizeGb() + */ + public Builder sizeGb(Integer sizeGb) { + this.sizeGb = sizeGb; + return this; + } + + /** + * @see Disk#getZone() + */ + public Builder zone(URI zone) { + this.zone = zone; + return this; + } + + /** + * @see Disk#getStatus() + */ + public Builder status(String status) { + this.status = status; + return this; + } + + + @Override + protected Builder self() { + return this; + } + + public Disk build() { + return new Disk(super.id, super.creationTimestamp, super.selfLink, super.name, + super.description, sizeGb, zone, status); + } + + public Builder fromDisk(Disk in) { + return super.fromResource(in) + .sizeGb(in.getSizeGb()) + .zone(in.getZone()) + .status(in.getStatus()); + } + + } + +} diff --git a/labs/google-compute/src/main/java/org/jclouds/googlecompute/features/DiskApi.java b/labs/google-compute/src/main/java/org/jclouds/googlecompute/features/DiskApi.java new file mode 100644 index 0000000000..026efbd280 --- /dev/null +++ b/labs/google-compute/src/main/java/org/jclouds/googlecompute/features/DiskApi.java @@ -0,0 +1,105 @@ +/* + * 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.Disk; +import org.jclouds.googlecompute.domain.ListPage; +import org.jclouds.googlecompute.domain.Operation; +import org.jclouds.googlecompute.options.ListOptions; +import org.jclouds.javax.annotation.Nullable; + +import java.net.URI; + +/** + * Provides synchronous access to Disks via their REST API. + * + * @author David Alves + * @see DiskAsyncApi + * @see + */ +public interface DiskApi { + + /** + * Returns the specified persistent disk resource. + * + * @param diskName name of the persistent disk resource to return. + * @return a Disk resource. + */ + Disk get(String diskName); + + /** + * Creates a persistent disk resource in the specified project specifying the size of the disk. + * + * @param diskName the name of disk. + * @param zone the URi of the zone where the disk is to be created. + * @param sizeGb the size of the disk + * @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. + */ + Operation insert(String diskName, URI zone, int sizeGb); + + /** + * Deletes the specified persistent disk resource. + * + * @param diskName name of the persistent disk 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. + */ + Operation delete(String diskName); + + /** + * @see DiskApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions) + */ + public ListPage listFirstPage(); + + /** + * @see DiskApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions) + */ + public ListPage listAtMarker(@Nullable String marker); + + + /** + * Retrieves the listPage of persistent disk resources contained within the specified project. + * By default the listPage 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 listPage + * @see ListOptions + * @see org.jclouds.googlecompute.domain.ListPage + */ + ListPage listAtMarker(@Nullable String marker, ListOptions listOptions); + + /** + * @see DiskApi#list(org.jclouds.googlecompute.options.ListOptions) + */ + public PagedIterable list(); + + /** + * A paged version of DiskApi#listPage() + * + * @return a Paged, Fluent Iterable that is able to fetch additional pages when required + * @see PagedIterable + * @see DiskApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions) + */ + PagedIterable list(ListOptions listOptions); +} diff --git a/labs/google-compute/src/main/java/org/jclouds/googlecompute/features/DiskAsyncApi.java b/labs/google-compute/src/main/java/org/jclouds/googlecompute/features/DiskAsyncApi.java new file mode 100644 index 0000000000..f4f0c99bb1 --- /dev/null +++ b/labs/google-compute/src/main/java/org/jclouds/googlecompute/features/DiskAsyncApi.java @@ -0,0 +1,157 @@ +/* + * 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.Disk; +import org.jclouds.googlecompute.domain.ListPage; +import org.jclouds.googlecompute.domain.Operation; +import org.jclouds.googlecompute.functions.internal.ParseDisks; +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.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; + +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; +import java.net.URI; + +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 Disks via their REST API. + * + * @author David Alves + * @see DiskApi + */ +@SkipEncoding({'/', '='}) +@RequestFilters(OAuthAuthenticator.class) +public interface DiskAsyncApi { + + /** + * @see DiskApi#get(String) + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Path("/disks/{disk}") + @OAuthScopes(COMPUTE_READONLY_SCOPE) + @Fallback(NullOnNotFoundOr404.class) + ListenableFuture get(@PathParam("disk") String diskName); + + /** + * @see DiskApi#insert(String, java.net.URI, int) + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/disks") + @OAuthScopes({COMPUTE_SCOPE}) + @MapBinder(BindToJsonPayload.class) + ListenableFuture insert(@PayloadParam("name") String diskName, + @PayloadParam("zone") URI zone, + @PayloadParam("sizeGb") int sizeGb); + + /** + * @see DiskApi#delete(String) + */ + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Path("/disks/{disk}") + @OAuthScopes(COMPUTE_SCOPE) + @Fallback(NullOnNotFoundOr404.class) + ListenableFuture delete(@PathParam("disk") String diskName); + + /** + * @see org.jclouds.googlecompute.features.DiskApi#listFirstPage() + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Path("/disks") + @OAuthScopes(COMPUTE_READONLY_SCOPE) + @ResponseParser(ParseDisks.class) + @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) + ListenableFuture> listFirstPage(); + + /** + * @see DiskApi#listAtMarker(String) + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Path("/disks") + @OAuthScopes(COMPUTE_READONLY_SCOPE) + @ResponseParser(ParseDisks.class) + @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) + ListenableFuture> listAtMarker(@QueryParam("pageToken") @Nullable String marker); + + /** + * @see DiskApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions) + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Path("/disks") + @OAuthScopes(COMPUTE_READONLY_SCOPE) + @ResponseParser(ParseDisks.class) + @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class) + ListenableFuture> listAtMarker(@QueryParam("pageToken") @Nullable String marker, ListOptions options); + + /** + * @see DiskApi#list(org.jclouds.googlecompute.options.ListOptions) + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Path("/disks") + @OAuthScopes(COMPUTE_READONLY_SCOPE) + @ResponseParser(ParseDisks.class) + @Transform(ParseDisks.ToPagedIterable.class) + @Fallback(EmptyPagedIterableOnNotFoundOr404.class) + ListenableFuture> list(); + + /** + * @see DiskApi#list(org.jclouds.googlecompute.options.ListOptions) + */ + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Path("/disks") + @OAuthScopes(COMPUTE_READONLY_SCOPE) + @ResponseParser(ParseDisks.class) + @Transform(ParseDisks.ToPagedIterable.class) + @Fallback(EmptyPagedIterableOnNotFoundOr404.class) + ListenableFuture> list(ListOptions options); +} diff --git a/labs/google-compute/src/main/java/org/jclouds/googlecompute/functions/internal/ParseDisks.java b/labs/google-compute/src/main/java/org/jclouds/googlecompute/functions/internal/ParseDisks.java new file mode 100644 index 0000000000..5973ebbb5a --- /dev/null +++ b/labs/google-compute/src/main/java/org/jclouds/googlecompute/functions/internal/ParseDisks.java @@ -0,0 +1,70 @@ +/* + * 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.Disk; +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 javax.inject.Singleton; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * @author David Alves + */ +@Singleton +public class ParseDisks extends ParseJson> { + + @Inject + public ParseDisks(Json json) { + super(json, new TypeLiteral>() {}); + } + + public static class ToPagedIterable extends BaseToPagedIterable { + + private final GoogleComputeApi api; + + @Inject + protected ToPagedIterable(GoogleComputeApi api) { + this.api = checkNotNull(api, "api"); + } + + @Override + protected Function> fetchNextPage(final String projectName, + final String marker, + final ListOptions options) { + return new Function>() { + + @Override + public IterableWithMarker apply(Object input) { + return api.getDiskApiForProject(projectName).listAtMarker(marker, options); + } + }; + } + } +} diff --git a/labs/google-compute/src/test/java/org/jclouds/googlecompute/features/DiskApiExpectTest.java b/labs/google-compute/src/test/java/org/jclouds/googlecompute/features/DiskApiExpectTest.java new file mode 100644 index 0000000000..aab522bf54 --- /dev/null +++ b/labs/google-compute/src/test/java/org/jclouds/googlecompute/features/DiskApiExpectTest.java @@ -0,0 +1,173 @@ +/* + * 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.options.ListOptions; +import org.jclouds.googlecompute.parse.ParseDiskListTest; +import org.jclouds.googlecompute.parse.ParseDiskTest; +import org.jclouds.googlecompute.parse.ParseOperationTest; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.testng.annotations.Test; + +import javax.ws.rs.core.MediaType; +import java.net.URI; + +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 DiskApiExpectTest extends BaseGoogleComputeApiExpectTest { + + public void testGetDiskResponseIs2xx() throws Exception { + HttpRequest get = HttpRequest + .builder() + .method("GET") + .endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/testimage1") + .addHeader("Accept", "application/json") + .addHeader("Authorization", "Bearer " + TOKEN).build(); + + HttpResponse operationResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/disk_get.json")).build(); + + DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE), + TOKEN_RESPONSE, get, operationResponse).getDiskApiForProject("myproject"); + + assertEquals(api.get("testimage1"), + new ParseDiskTest().expected()); + } + + public void testGetDiskResponseIs4xx() throws Exception { + HttpRequest get = HttpRequest + .builder() + .method("GET") + .endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/testimage1") + .addHeader("Accept", "application/json") + .addHeader("Authorization", "Bearer " + TOKEN).build(); + + HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build(); + + DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE), + TOKEN_RESPONSE, get, operationResponse).getDiskApiForProject("myproject"); + + assertNull(api.get("testimage1")); + } + + public void testInsertDiskResponseIs2xx() { + HttpRequest insert = HttpRequest + .builder() + .method("POST") + .endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks") + .addHeader("Accept", "application/json") + .addHeader("Authorization", "Bearer " + TOKEN) + .payload(payloadFromResourceWithContentType("/disk_insert.json", MediaType.APPLICATION_JSON)) + .build(); + + HttpResponse insertDiskResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/operation.json")).build(); + + DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE), + TOKEN_RESPONSE, insert, + insertDiskResponse).getDiskApiForProject("myproject"); + + assertEquals(api.insert("testimage1", URI.create("https://www.googleapis" + + ".com/compute/v1beta13/projects/myproject/zones/us-central1-a"), 1) + , new ParseOperationTest().expected()); + } + + public void testDeleteDiskResponseIs2xx() { + HttpRequest delete = HttpRequest + .builder() + .method("DELETE") + .endpoint("https://www.googleapis" + + ".com/compute/v1beta13/projects/myproject/disks/testimage1") + .addHeader("Accept", "application/json") + .addHeader("Authorization", "Bearer " + TOKEN).build(); + + HttpResponse deleteResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/operation.json")).build(); + + DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE), + TOKEN_RESPONSE, delete, deleteResponse).getDiskApiForProject("myproject"); + + assertEquals(api.delete("testimage1"), + new ParseOperationTest().expected()); + } + + public void testDeleteDiskResponseIs4xx() { + HttpRequest delete = HttpRequest + .builder() + .method("DELETE") + .endpoint("https://www.googleapis" + + ".com/compute/v1beta13/projects/myproject/disks/testimage1") + .addHeader("Accept", "application/json") + .addHeader("Authorization", "Bearer " + TOKEN).build(); + + HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build(); + + DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE), + TOKEN_RESPONSE, delete, deleteResponse).getDiskApiForProject("myproject"); + + assertNull(api.delete("testimage1")); + } + + public void testListDisksResponseIs2xx() { + HttpRequest list = HttpRequest + .builder() + .method("GET") + .endpoint("https://www.googleapis" + + ".com/compute/v1beta13/projects/myproject/disks") + .addHeader("Accept", "application/json") + .addHeader("Authorization", "Bearer " + TOKEN).build(); + + HttpResponse operationResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/disk_list.json")).build(); + + DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE), + TOKEN_RESPONSE, list, operationResponse).getDiskApiForProject("myproject"); + + assertEquals(api.listFirstPage().toString(), + new ParseDiskListTest().expected().toString()); + } + + public void testListDisksResponseIs4xx() { + HttpRequest list = HttpRequest + .builder() + .method("GET") + .endpoint("https://www.googleapis" + + ".com/compute/v1beta13/projects/myproject/disks") + .addHeader("Accept", "application/json") + .addHeader("Authorization", "Bearer " + TOKEN).build(); + + HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build(); + + DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE), + TOKEN_RESPONSE, list, operationResponse).getDiskApiForProject("myproject"); + + assertTrue(api.list().concat().isEmpty()); + } +} diff --git a/labs/google-compute/src/test/java/org/jclouds/googlecompute/features/DiskApiLiveTest.java b/labs/google-compute/src/test/java/org/jclouds/googlecompute/features/DiskApiLiveTest.java new file mode 100644 index 0000000000..e8523d56aa --- /dev/null +++ b/labs/google-compute/src/test/java/org/jclouds/googlecompute/features/DiskApiLiveTest.java @@ -0,0 +1,101 @@ +/* + * 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.PagedIterable; +import org.jclouds.googlecompute.domain.Disk; +import org.jclouds.googlecompute.domain.Project; +import org.jclouds.googlecompute.internal.BaseGoogleComputeApiLiveTest; +import org.jclouds.googlecompute.options.ListOptions; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.net.URI; +import java.util.List; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +/** + * @author David Alves + */ +public class DiskApiLiveTest extends BaseGoogleComputeApiLiveTest { + + private static final String DISK_NAME = "disk-api-live-test-disk"; + private static final int TIME_WAIT = 10; + + private URI zoneUrl; + private int sizeGb; + + @BeforeClass(groups = {"integration", "live"}) + public void setupContext() { + super.setupContext(); + sizeGb = 1; + } + + private DiskApi api() { + return context.getApi().getDiskApiForProject( getUserProject()); + } + + @Test(groups = "live") + public void testInsertDisk() { + Project project = context.getApi().getProjectApi().get(getUserProject()); + zoneUrl = getDefaultZoneUrl(project.getName()); + assertOperationDoneSucessfully(api().insert(DISK_NAME, zoneUrl, sizeGb), TIME_WAIT); + + } + + @Test(groups = "live", dependsOnMethods = "testInsertDisk") + public void testGetDisk() { + + Disk disk = api().get(DISK_NAME); + assertNotNull(disk); + assertDiskEquals(disk); + } + + @Test(groups = "live", dependsOnMethods = "testGetDisk") + public void testListDisk() { + + PagedIterable disks = api().list(new ListOptions.Builder() + .filter("name eq " + DISK_NAME)); + + List disksAsList = Lists.newArrayList(disks.concat()); + + assertEquals(disksAsList.size(), 1); + + assertDiskEquals(Iterables.getOnlyElement(disksAsList)); + + } + + @Test(groups = "live", dependsOnMethods = "testListDisk") + public void testDeleteDisk() { + + assertOperationDoneSucessfully(api().delete(DISK_NAME), TIME_WAIT); + } + + private void assertDiskEquals(Disk result) { + assertEquals(result.getName(), DISK_NAME); + assertEquals(result.getSizeGb(), sizeGb); + assertEquals(result.getZone(), zoneUrl); + } + +} diff --git a/labs/google-compute/src/test/java/org/jclouds/googlecompute/parse/ParseDiskListTest.java b/labs/google-compute/src/test/java/org/jclouds/googlecompute/parse/ParseDiskListTest.java new file mode 100644 index 0000000000..c18ada4cec --- /dev/null +++ b/labs/google-compute/src/test/java/org/jclouds/googlecompute/parse/ParseDiskListTest.java @@ -0,0 +1,65 @@ +/* + * 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.Disk; +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 ParseDiskListTest extends BaseGoogleComputeParseTest> { + + @Override + public String resource() { + return "/disk_list.json"; + } + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public ListPage expected() { + return ListPage.builder() + .kind(Resource.Kind.DISK_LIST) + .id("projects/myproject/disks") + .selfLink(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks")) + .items(ImmutableSet.of(Disk.builder() + .id("13050421646334304115") + .creationTimestamp(new SimpleDateFormatDateService().iso8601DateParse("2012-11-25T01:38:48.306")) + .selfLink(URI.create("https://www.googleapis" + + ".com/compute/v1beta13/projects/myproject/disks/testimage1")) + .name("testimage1") + .sizeGb(1) + .zone(URI.create("https://www.googleapis" + + ".com/compute/v1beta13/projects/myproject/zones/us-central1-a")) + .status("READY") + .build()) + ).build(); + } +} diff --git a/labs/google-compute/src/test/java/org/jclouds/googlecompute/parse/ParseDiskTest.java b/labs/google-compute/src/test/java/org/jclouds/googlecompute/parse/ParseDiskTest.java new file mode 100644 index 0000000000..3cd38d1e66 --- /dev/null +++ b/labs/google-compute/src/test/java/org/jclouds/googlecompute/parse/ParseDiskTest.java @@ -0,0 +1,55 @@ +/* + * 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.Disk; +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 ParseDiskTest extends BaseGoogleComputeParseTest { + + @Override + public String resource() { + return "/disk_get.json"; + } + + @Override + @Consumes(MediaType.APPLICATION_JSON) + public Disk expected() { + return Disk.builder() + .id("13050421646334304115") + .creationTimestamp(new SimpleDateFormatDateService().iso8601DateParse("2012-11-25T01:38:48.306")) + .selfLink(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/testimage1")) + .name("testimage1") + .sizeGb(1) + .zone(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a")) + .status("READY") + .build(); + } +} diff --git a/labs/google-compute/src/test/resources/disk_get.json b/labs/google-compute/src/test/resources/disk_get.json new file mode 100644 index 0000000000..5c7ce0c251 --- /dev/null +++ b/labs/google-compute/src/test/resources/disk_get.json @@ -0,0 +1,10 @@ +{ + "kind": "compute#disk", + "id": "13050421646334304115", + "creationTimestamp": "2012-11-25T01:38:48.306", + "selfLink": "https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/testimage1", + "name": "testimage1", + "sizeGb": "1", + "zone": "https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a", + "status": "READY" +} \ No newline at end of file diff --git a/labs/google-compute/src/test/resources/disk_insert.json b/labs/google-compute/src/test/resources/disk_insert.json new file mode 100644 index 0000000000..32332cf806 --- /dev/null +++ b/labs/google-compute/src/test/resources/disk_insert.json @@ -0,0 +1 @@ +{"name":"testimage1","zone":"https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a","sizeGb":1} \ No newline at end of file diff --git a/labs/google-compute/src/test/resources/disk_list.json b/labs/google-compute/src/test/resources/disk_list.json new file mode 100644 index 0000000000..8b09831d77 --- /dev/null +++ b/labs/google-compute/src/test/resources/disk_list.json @@ -0,0 +1,17 @@ +{ + "kind": "compute#diskList", + "id": "projects/myproject/disks", + "selfLink": "https://www.googleapis.com/compute/v1beta13/projects/myproject/disks", + "items": [ + { + "kind": "compute#disk", + "id": "13050421646334304115", + "creationTimestamp": "2012-11-25T01:38:48.306", + "selfLink": "https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/testimage1", + "name": "testimage1", + "sizeGb": "1", + "zone": "https://www.googleapis.com/compute/v1beta13/projects/myproject/zones/us-central1-a", + "status": "READY" + } + ] +} \ No newline at end of file