From 2ccf08962e764dc777574757c333fb3d4b70ce23 Mon Sep 17 00:00:00 2001 From: Daniel Broudy Date: Thu, 20 Nov 2014 19:02:14 -0800 Subject: [PATCH] Added TargetInstanceApi --- .../GoogleComputeEngineApi.java | 6 + .../domain/NewTargetInstance.java | 72 ++++++++++ .../domain/TargetInstance.java | 48 +++++++ .../features/AggregatedListApi.java | 51 +++++++ .../features/TargetInstanceApi.java | 129 ++++++++++++++++++ .../features/AggregatedListApiLiveTest.java | 18 +++ .../features/AggregatedListApiMockTest.java | 20 +++ .../features/TargetInstanceApiLiveTest.java | 77 +++++++++++ .../features/TargetInstanceApiMockTest.java | 101 ++++++++++++++ .../parse/ParseTargetInstanceListTest.java | 60 ++++++++ .../parse/ParseTargetInstanceTest.java | 51 +++++++ .../aggregated_target_instance_list.json | 128 +++++++++++++++++ ...aggregated_target_instance_list_empty.json | 55 ++++++++ .../test/resources/target_instance_get.json | 11 ++ .../resources/target_instance_insert.json | 6 + .../test/resources/target_instance_list.json | 30 ++++ 16 files changed, 863 insertions(+) create mode 100644 providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/NewTargetInstance.java create mode 100644 providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/TargetInstance.java create mode 100644 providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/TargetInstanceApi.java create mode 100644 providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/TargetInstanceApiLiveTest.java create mode 100644 providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/TargetInstanceApiMockTest.java create mode 100644 providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseTargetInstanceListTest.java create mode 100644 providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseTargetInstanceTest.java create mode 100644 providers/google-compute-engine/src/test/resources/aggregated_target_instance_list.json create mode 100644 providers/google-compute-engine/src/test/resources/aggregated_target_instance_list_empty.json create mode 100644 providers/google-compute-engine/src/test/resources/target_instance_get.json create mode 100644 providers/google-compute-engine/src/test/resources/target_instance_insert.json create mode 100644 providers/google-compute-engine/src/test/resources/target_instance_list.json diff --git a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java index 8a6e36c37f..14a3961801 100644 --- a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java +++ b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java @@ -39,6 +39,7 @@ import org.jclouds.googlecomputeengine.features.ProjectApi; import org.jclouds.googlecomputeengine.features.RegionApi; import org.jclouds.googlecomputeengine.features.RouteApi; import org.jclouds.googlecomputeengine.features.SnapshotApi; +import org.jclouds.googlecomputeengine.features.TargetInstanceApi; import org.jclouds.googlecomputeengine.features.TargetPoolApi; import org.jclouds.googlecomputeengine.features.TargetHttpProxyApi; import org.jclouds.googlecomputeengine.features.UrlMapApi; @@ -135,6 +136,11 @@ public interface GoogleComputeEngineApi extends Closeable { @Endpoint(CurrentProject.class) TargetHttpProxyApi targetHttpProxies(); + @Delegate + @Endpoint(CurrentProject.class) + @Path("/zones/{zone}") + TargetInstanceApi targetInstancesInZone(@PathParam("zone") String zone); + @Delegate @Endpoint(CurrentProject.class) @Path("/regions/{region}") diff --git a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/NewTargetInstance.java b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/NewTargetInstance.java new file mode 100644 index 0000000000..478bfced47 --- /dev/null +++ b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/NewTargetInstance.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine.domain; + +import java.net.URI; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class NewTargetInstance { + + public abstract String name(); + @Nullable public abstract String description(); + @Nullable public abstract String natPolicy(); + @Nullable public abstract URI instance(); + + @SerializedNames({"name", "description", "natPolicy", "instance"}) + static NewTargetInstance create(String name, String description, String natPolicy, URI instance){ + return new AutoValue_NewTargetInstance(name, description, natPolicy, instance); + } + + NewTargetInstance() { + } + + public static class Builder { + private String name; + private String description; + private String natPolicy; + private URI instance; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Builder natPolicy(String natPolicy) { + this.natPolicy = natPolicy; + return this; + } + + public Builder instance(URI instance) { + this.instance = instance; + return this; + } + + public NewTargetInstance build() { + return NewTargetInstance.create(name, description, natPolicy, instance); + } + } +} diff --git a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/TargetInstance.java b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/TargetInstance.java new file mode 100644 index 0000000000..656bc8ffc9 --- /dev/null +++ b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/TargetInstance.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine.domain; + + +import java.net.URI; + +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.json.SerializedNames; + +import com.google.auto.value.AutoValue; + +@AutoValue +public abstract class TargetInstance { + + public abstract String creationTimestamp(); + public abstract String name(); + @Nullable public abstract String description(); + public abstract URI zone(); + public abstract String natPolicy(); + @Nullable public abstract URI instance(); + public abstract URI selfLink(); + + @SerializedNames({"creationTimestamp", "name", "description", "zone", + "natPolicy", "instance", "selfLink"}) + public static TargetInstance create(String creationTimestamp, String name, + String description, URI zone, String natPolicy, URI instance, URI selfLink){ + return new AutoValue_TargetInstance(creationTimestamp, name, description, zone, + natPolicy, instance, selfLink); + } + + TargetInstance(){ + } +} diff --git a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AggregatedListApi.java b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AggregatedListApi.java index de12f51304..55ff6b238e 100644 --- a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AggregatedListApi.java +++ b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/AggregatedListApi.java @@ -36,6 +36,7 @@ import org.jclouds.googlecomputeengine.domain.ForwardingRule; import org.jclouds.googlecomputeengine.domain.Instance; import org.jclouds.googlecomputeengine.domain.MachineType; import org.jclouds.googlecomputeengine.domain.Operation; +import org.jclouds.googlecomputeengine.domain.TargetInstance; import org.jclouds.googlecomputeengine.internal.BaseToIteratorOfListPage; import org.jclouds.googlecomputeengine.options.ListOptions; import org.jclouds.javax.annotation.Nullable; @@ -396,4 +397,54 @@ public interface AggregatedListApi { }; } } + + /** + * Retrieves the list of TargetInstance 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 pageToken + * marks the beginning of the next list page + * @param listOptions + * listing options + * @return a page of the list + */ + @Named("TargetInstances:aggregatedList") + @GET + @Path("/targetInstances") + ListPage pageOfTargetInstances(@Nullable @QueryParam("pageToken") String pageToken, + ListOptions listOptions); + + /** @see #pageOfTargetInstances(String, ListOptions) */ + @Named("TargetInstances:aggregatedList") + @GET + @Path("/targetInstances") + @Transform(TargetInstancePages.class) + Iterator> targetInstances(); + + /** @see #pageOfTargetInstances(String, ListOptions) */ + @Named("TargetInstances:aggregatedList") + @GET + @Path("/targetInstances") + @Transform(TargetInstancePages.class) + Iterator> targetInstances(ListOptions options); + + static final class TargetInstancePages extends BaseToIteratorOfListPage { + private final GoogleComputeEngineApi api; + + @Inject + TargetInstancePages(GoogleComputeEngineApi api) { + this.api = api; + } + + @Override + protected Function> fetchNextPage(final ListOptions options) { + return new Function>() { + @Override + public ListPage apply(String pageToken) { + return api.aggregatedList().pageOfTargetInstances(pageToken, options); + } + }; + } + } } diff --git a/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/TargetInstanceApi.java b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/TargetInstanceApi.java new file mode 100644 index 0000000000..6d2c3ccf13 --- /dev/null +++ b/providers/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/TargetInstanceApi.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine.features; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +import java.util.Iterator; + +import javax.inject.Inject; +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 org.jclouds.Fallbacks.NullOnNotFoundOr404; +import org.jclouds.googlecloud.domain.ListPage; +import org.jclouds.googlecomputeengine.GoogleComputeEngineApi; +import org.jclouds.googlecomputeengine.domain.NewTargetInstance; +import org.jclouds.googlecomputeengine.domain.Operation; +import org.jclouds.googlecomputeengine.domain.TargetInstance; +import org.jclouds.googlecomputeengine.internal.BaseCallerArg0ToIteratorOfListPage; +import org.jclouds.googlecomputeengine.options.ListOptions; +import org.jclouds.javax.annotation.Nullable; +import org.jclouds.oauth.v2.filters.OAuthFilter; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.annotations.Transform; +import org.jclouds.rest.binders.BindToJsonPayload; + +import com.google.common.base.Function; + +@SkipEncoding({'/', '='}) +@RequestFilters(OAuthFilter.class) +@Path("/targetInstances") +@Consumes(APPLICATION_JSON) +public interface TargetInstanceApi { + + /** Returns a targetInstance by name or null if not found. */ + @Named("TargetInstances:get") + @GET + @Path("/{targetInstance}") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + TargetInstance get(@PathParam("targetInstance") String targetInstance); + + /** + * Creates a instance resource in the specified project using the data included in the request. + * + * @param template the instance template + * @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("TargetInstances:insert") + @POST + @Produces(APPLICATION_JSON) + Operation create(@BinderParam(BindToJsonPayload.class) NewTargetInstance targetInstance); + + /** Deletes a targetInstance by name and returns the operation in progress, or null if not found. */ + @Named("TargetInstances:delete") + @DELETE + @Path("/{targetInstance}") + @Fallback(NullOnNotFoundOr404.class) + @Nullable + Operation delete(@PathParam("targetInstance") String targetInstance); + + /** + * Retrieves the list of targetInstance 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 pageToken marks the beginning of the next list page + * @param listOptions listing options + * @return a page of the list + */ + @Named("TargetInstances:list") + @GET + ListPage listPage(@Nullable @QueryParam("pageToken") String pageToken, ListOptions listOptions); + + /** @see #listPage(String, ListOptions) */ + @Named("TargetInstances:list") + @GET + @Transform(TargetInstancePages.class) + Iterator> list(); + + /** @see #listPage(String, ListOptions) */ + @Named("TargetInstances:list") + @GET + @Transform(TargetInstancePages.class) + Iterator> list(ListOptions options); + + static final class TargetInstancePages extends BaseCallerArg0ToIteratorOfListPage { + + private final GoogleComputeEngineApi api; + + @Inject TargetInstancePages(GoogleComputeEngineApi api) { + this.api = api; + } + + @Override + protected Function> fetchNextPage(final String zoneName, final ListOptions options) { + return new Function>() { + @Override public ListPage apply(String pageToken) { + return api.targetInstancesInZone(zoneName).listPage(pageToken, options); + } + }; + } + } +} diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiLiveTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiLiveTest.java index e11987281c..c1e2f62bb6 100644 --- a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiLiveTest.java +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiLiveTest.java @@ -30,6 +30,7 @@ import org.jclouds.googlecomputeengine.domain.DiskType; import org.jclouds.googlecomputeengine.domain.ForwardingRule; import org.jclouds.googlecomputeengine.domain.MachineType; import org.jclouds.googlecomputeengine.domain.Operation; +import org.jclouds.googlecomputeengine.domain.TargetInstance; import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest; import org.testng.SkipException; import org.testng.annotations.Test; @@ -129,4 +130,21 @@ public class AggregatedListApiLiveTest extends BaseGoogleComputeEngineApiLiveTes } assertEquals(count, 2); } + + public void targetInstances() { + Iterator> pageIterator = api().targetInstances(maxResults(1)); + // make sure that in spite of having only one result per page we get at + // least two results + int count = 0; + for (; count < 2 && pageIterator.hasNext();) { + ListPage result = pageIterator.next(); + if (!result.isEmpty()) { + count++; + } + } + if (count < 2) { + throw new SkipException("Not enough target instances"); + } + assertEquals(count, 2); + } } diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiMockTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiMockTest.java index ea396192ab..a02ec0757b 100644 --- a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiMockTest.java +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AggregatedListApiMockTest.java @@ -164,4 +164,24 @@ public class AggregatedListApiMockTest extends BaseGoogleComputeEngineApiMockTes assertSent(server, "GET", "/projects/party/aggregated/forwardingRules"); } + + public void targetInstances() throws Exception { + server.enqueue(jsonResponse("/aggregated_target_instance_list.json")); + + AggregatedListApi aggregatedList = api().aggregatedList(); + + assertTrue(aggregatedList.targetInstances().hasNext()); + + assertSent(server, "GET", "/projects/party/aggregated/targetInstances"); + } + + public void targetInstancesResponseIs4xx() throws Exception { + server.enqueue(jsonResponse("/aggregated_target_instance_list_empty.json")); + + AggregatedListApi aggregatedList = api().aggregatedList(); + + assertFalse(aggregatedList.targetInstances().hasNext()); + + assertSent(server, "GET", "/projects/party/aggregated/targetInstances"); + } } diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/TargetInstanceApiLiveTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/TargetInstanceApiLiveTest.java new file mode 100644 index 0000000000..3b25b40b28 --- /dev/null +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/TargetInstanceApiLiveTest.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine.features; + +import static org.jclouds.googlecomputeengine.options.ListOptions.Builder.filter; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import org.jclouds.googlecloud.domain.ListPage; +import org.jclouds.googlecomputeengine.domain.NewTargetInstance; +import org.jclouds.googlecomputeengine.domain.TargetInstance; +import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest; +import org.testng.annotations.Test; + +import com.google.common.collect.Iterables; + + +public class TargetInstanceApiLiveTest extends BaseGoogleComputeEngineApiLiveTest { + + public static final String TARGET_INSTANCE_NAME = "test-target-instance-1"; + + @Test(groups = "live") + public void testInsertTargetInstance(){ + + NewTargetInstance newTargetInstance = new NewTargetInstance.Builder() + .name(TARGET_INSTANCE_NAME) + .description("A test Target Instance") + .build(); + + assertOperationDoneSuccessfully(api.targetInstancesInZone(DEFAULT_ZONE_NAME).create(newTargetInstance)); + } + + @Test(groups = "live", dependsOnMethods = "testInsertTargetInstance") + public void testGetTargetInstance(){ + TargetInstance targetInstance = api.targetInstancesInZone(DEFAULT_ZONE_NAME).get(TARGET_INSTANCE_NAME); + + assertNotNull(targetInstance); + assertEquals(targetInstance.name(), TARGET_INSTANCE_NAME); + assertEquals(targetInstance.description(), "A test Target Instance"); + assertEquals(targetInstance.zone(), getZoneUrl(DEFAULT_ZONE_NAME)); + } + + @Test(groups = "live", dependsOnMethods = "testInsertTargetInstance", alwaysRun = true) + public void testListTargetInstance(){ + ListPage targetInstances = api.targetInstancesInZone(DEFAULT_ZONE_NAME) + .list(filter("name eq " + TARGET_INSTANCE_NAME)).next(); + + assertEquals(targetInstances.size(), 1); + assertTargetInstanceEquals(Iterables.getOnlyElement(targetInstances)); + } + + @Test(groups = "live", dependsOnMethods = {"testListTargetInstance", "testGetTargetInstance"}, alwaysRun = true) + public void testDeleteTargetInstance(){ + assertOperationDoneSuccessfully(api.targetInstancesInZone(DEFAULT_ZONE_NAME).delete(TARGET_INSTANCE_NAME)); + } + + private void assertTargetInstanceEquals(TargetInstance targetInstance){ + assertNotNull(targetInstance); + assertEquals(targetInstance.name(), TARGET_INSTANCE_NAME); + assertEquals(targetInstance.description(), "A test Target Instance"); + assertEquals(targetInstance.zone(), getZoneUrl(DEFAULT_ZONE_NAME)); + } +} diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/TargetInstanceApiMockTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/TargetInstanceApiMockTest.java new file mode 100644 index 0000000000..2bca642f20 --- /dev/null +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/TargetInstanceApiMockTest.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine.features; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNull; + +import java.net.URI; + +import org.jclouds.googlecomputeengine.domain.NewTargetInstance; +import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiMockTest; +import org.jclouds.googlecomputeengine.parse.ParseOperationTest; +import org.jclouds.googlecomputeengine.parse.ParseTargetInstanceListTest; +import org.jclouds.googlecomputeengine.parse.ParseTargetInstanceTest; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "TargetInstanceApiMockTest", singleThreaded = true) +public class TargetInstanceApiMockTest extends BaseGoogleComputeEngineApiMockTest { + + public static String TARGET_INSTANCE_NAME = "target-instance-1"; + + public void get() throws Exception { + server.enqueue(jsonResponse("/target_instance_get.json")); + + assertEquals(targetInstanceApi().get(TARGET_INSTANCE_NAME), + new ParseTargetInstanceTest().expected(url("/projects"))); + assertSent(server, "GET", "/projects/party/zones/us-central1-a/targetInstances/" + TARGET_INSTANCE_NAME); + } + + public void get_4xx() throws Exception { + server.enqueue(response404()); + + assertNull(targetInstanceApi().get(TARGET_INSTANCE_NAME)); + assertSent(server, "GET", "/projects/party/zones/us-central1-a/targetInstances/" + TARGET_INSTANCE_NAME); + } + + public void insert() throws Exception { + server.enqueue(jsonResponse("/operation.json")); + + NewTargetInstance options = new NewTargetInstance.Builder() + .name("test-target-instance") + .description("This is a test") + .natPolicy("NO_NAT") + .instance(URI.create(url("/projects/party/zones/us-central1-a/instances/instance-1"))) + .build(); + + assertEquals(targetInstanceApi().create(options), + new ParseOperationTest().expected(url("/projects"))); + + assertSent(server, "POST", "/projects/party/zones/us-central1-a/targetInstances", + stringFromResource("/target_instance_insert.json")); + } + + public void testDeleteImageResponseIs2xx() throws Exception { + server.enqueue(jsonResponse("/operation.json")); + + assertEquals(targetInstanceApi().delete(TARGET_INSTANCE_NAME), + new ParseOperationTest().expected(url("/projects"))); + assertSent(server, "DELETE", "/projects/party/zones/us-central1-a/targetInstances/" + TARGET_INSTANCE_NAME); + } + + public void delete() throws Exception { + server.enqueue(response404()); + + assertNull(targetInstanceApi().delete(TARGET_INSTANCE_NAME)); + assertSent(server, "DELETE", "/projects/party/zones/us-central1-a/targetInstances/" + TARGET_INSTANCE_NAME); + } + + public void list() throws InterruptedException { + server.enqueue(jsonResponse("/target_instance_list.json")); + + assertEquals(targetInstanceApi().list().next(), new ParseTargetInstanceListTest().expected(url("/projects"))); + assertSent(server, "GET", "/projects/party/zones/us-central1-a/targetInstances"); + } + + public void listEmpty() throws InterruptedException { + server.enqueue(jsonResponse("/list_empty.json")); + + assertFalse(targetInstanceApi().list().hasNext()); + assertSent(server, "GET", "/projects/party/zones/us-central1-a/targetInstances"); + } + + TargetInstanceApi targetInstanceApi() { + return api().targetInstancesInZone("us-central1-a"); + } +} diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseTargetInstanceListTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseTargetInstanceListTest.java new file mode 100644 index 0000000000..4af9d4dfbf --- /dev/null +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseTargetInstanceListTest.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine.parse; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +import java.net.URI; + +import javax.ws.rs.Consumes; + +import org.jclouds.googlecloud.domain.ForwardingListPage; +import org.jclouds.googlecloud.domain.ListPage; +import org.jclouds.googlecomputeengine.domain.TargetInstance; +import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; + +@Test(groups = "unit", testName = "ParseTargetInstanceListTest") +public class ParseTargetInstanceListTest extends BaseGoogleComputeEngineParseTest> { + + @Override + public String resource() { + return "/target_instance_list.json"; + } + + @Override @Consumes(APPLICATION_JSON) + public ListPage expected() { + return expected(BASE_URL); + } + + public ListPage expected(String baseURL){ + return ForwardingListPage.create( // + ImmutableList.of(new ParseTargetInstanceTest().expected(baseURL), + TargetInstance.create("2014-11-20T17:35:17.268-08:00", // creationTimestamp + "target-instance-2", // name + null, // description + URI.create(baseURL + "/party/zones/us-central1-a"), // zone + "NO_NAT", // natPolicy + URI.create(baseURL + "/party/zones/us-central1-a/instances/test-3"), // instance + URI.create(baseURL + "/party/zones/us-central1-a/targetInstances/target-instance-2") // selfLink + )), // items + null // nextPageToken + ); + } +} diff --git a/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseTargetInstanceTest.java b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseTargetInstanceTest.java new file mode 100644 index 0000000000..deae9f4117 --- /dev/null +++ b/providers/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseTargetInstanceTest.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine.parse; + +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + +import java.net.URI; + +import javax.ws.rs.Consumes; + +import org.jclouds.googlecomputeengine.domain.TargetInstance; +import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "ParseTargetInstanceTest") +public class ParseTargetInstanceTest extends BaseGoogleComputeEngineParseTest { + + @Override + public String resource() { + return "/target_instance_get.json"; + } + + @Override @Consumes(APPLICATION_JSON) + public TargetInstance expected() { + return expected(BASE_URL); + } + + public TargetInstance expected(String baseUrl) { + return TargetInstance.create("2014-07-18T09:47:30.826-07:00", // creationTimestamp + "target-instance-1", // name + "A pretty cool target instance", // description + URI.create(baseUrl + "/party/zones/us-central1-a"), // zone + "NO_NAT", // natPolicy + URI.create(baseUrl + "/party/zones/us-central1-a/instances/test-0"), // instance + URI.create(baseUrl + "/party/zones/us-central1-a/targetInstances/target-instance-1")); //selfLink + } +} diff --git a/providers/google-compute-engine/src/test/resources/aggregated_target_instance_list.json b/providers/google-compute-engine/src/test/resources/aggregated_target_instance_list.json new file mode 100644 index 0000000000..e1e56b95b2 --- /dev/null +++ b/providers/google-compute-engine/src/test/resources/aggregated_target_instance_list.json @@ -0,0 +1,128 @@ +{ + "kind": "compute#targetInstanceAggregatedList", + "selfLink": "https://www.googleapis.com/compute/v1/projects/party/aggregated/targetInstances", + "id": "projects/party/aggregated/targetInstances", + "items": { + "zones/asia-east1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'zones/asia-east1-a' on this page.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-a" + } + ] + } + }, + "zones/asia-east1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'zones/asia-east1-b' on this page.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-b" + } + ] + } + }, + "zones/asia-east1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'zones/asia-east1-c' on this page.", + "data": [ + { + "key": "scope", + "value": "zones/asia-east1-c" + } + ] + } + }, + "zones/europe-west1-a": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'zones/europe-west1-a' on this page.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-a" + } + ] + } + }, + "zones/europe-west1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'zones/europe-west1-b' on this page.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-b" + } + ] + } + }, + "zones/europe-west1-c": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'zones/europe-west1-c' on this page.", + "data": [ + { + "key": "scope", + "value": "zones/europe-west1-c" + } + ] + } + }, + "zones/us-central1-a": { + "targetInstances": [ + { + + "kind": "compute#targetInstance", + "id": "3191835352771895826", + "creationTimestamp": "2014-11-24T10:42:45.135-08:00", + "name": "test-target-instance", + "zone": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a", + "natPolicy": "NO_NAT", + "instance": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/instances/instance-1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/targetInstances/test-target-instance" + }, + { + + "kind": "compute#targetInstance", + "id": "7362436693678237415", + "creationTimestamp": "2014-11-20T17:35:17.268-08:00", + "name": "target-instance-1", + "zone": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a", + "natPolicy": "NO_NAT", + "selfLink": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/targetInstances/target-instance-1" + } + ] + }, + "zones/us-central1-b": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'zones/us-central1-b' on this page.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-b" + } + ] + } + }, + "zones/us-central1-f": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'zones/us-central1-f' on this page.", + "data": [ + { + "key": "scope", + "value": "zones/us-central1-f" + } + ] + } + } + } +} \ No newline at end of file diff --git a/providers/google-compute-engine/src/test/resources/aggregated_target_instance_list_empty.json b/providers/google-compute-engine/src/test/resources/aggregated_target_instance_list_empty.json new file mode 100644 index 0000000000..e1a852c88e --- /dev/null +++ b/providers/google-compute-engine/src/test/resources/aggregated_target_instance_list_empty.json @@ -0,0 +1,55 @@ +{ + "kind": "compute#addressAggregatedList", + "selfLink": "https://www.googleapis.com/compute/v1/projects/studied-point-720/aggregated/addresses", + "id": "projects/studied-point-720/aggregated/addresses", + "items": { + "regions/asia-east1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'regions/asia-east1' on this page.", + "data": [ + { + "key": "scope", + "value": "regions/asia-east1" + } + ] + } + }, + "regions/europe-west1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'regions/europe-west1' on this page.", + "data": [ + { + "key": "scope", + "value": "regions/europe-west1" + } + ] + } + }, + "regions/us-central1": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'regions/us-central1' on this page.", + "data": [ + { + "key": "scope", + "value": "regions/us-central1" + } + ] + } + }, + "global": { + "warning": { + "code": "NO_RESULTS_ON_PAGE", + "message": "There are no results for scope 'global' on this page.", + "data": [ + { + "key": "scope", + "value": "global" + } + ] + } + } + } +} \ No newline at end of file diff --git a/providers/google-compute-engine/src/test/resources/target_instance_get.json b/providers/google-compute-engine/src/test/resources/target_instance_get.json new file mode 100644 index 0000000000..89607d81ca --- /dev/null +++ b/providers/google-compute-engine/src/test/resources/target_instance_get.json @@ -0,0 +1,11 @@ +{ + "kind": "compute#targetInstance", + "id": 13050421646334304115, + "creationTimestamp": "2014-07-18T09:47:30.826-07:00", + "name": "target-instance-1", + "description": "A pretty cool target instance", + "zone": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a", + "natPolicy": "NO_NAT", + "instance": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/instances/test-0", + "selfLink": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/targetInstances/target-instance-1" +} \ No newline at end of file diff --git a/providers/google-compute-engine/src/test/resources/target_instance_insert.json b/providers/google-compute-engine/src/test/resources/target_instance_insert.json new file mode 100644 index 0000000000..9e76ef8616 --- /dev/null +++ b/providers/google-compute-engine/src/test/resources/target_instance_insert.json @@ -0,0 +1,6 @@ +{ + "name": "test-target-instance", + "description": "This is a test", + "natPolicy": "NO_NAT", + "instance": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/instances/instance-1" +} \ No newline at end of file diff --git a/providers/google-compute-engine/src/test/resources/target_instance_list.json b/providers/google-compute-engine/src/test/resources/target_instance_list.json new file mode 100644 index 0000000000..7e5e2c2f28 --- /dev/null +++ b/providers/google-compute-engine/src/test/resources/target_instance_list.json @@ -0,0 +1,30 @@ +{ + "kind": "compute#targetInstanceList", + "selfLink": "https://www.googleapis.com/compute/v1/projects/studied-point-720/zones/us-central1-a/targetInstances", + "id": "projects/studied-point-720/zones/us-central1-a/targetInstances", + "items": [ + { + + "kind": "compute#targetInstance", + "id": "13050421646334304115", + "creationTimestamp": "2014-07-18T09:47:30.826-07:00", + "name": "target-instance-1", + "description": "A pretty cool target instance", + "zone": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a", + "natPolicy": "NO_NAT", + "instance": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/instances/test-0", + "selfLink": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/targetInstances/target-instance-1" + }, + { + + "kind": "compute#targetInstance", + "id": "7362436693678237415", + "creationTimestamp": "2014-11-20T17:35:17.268-08:00", + "name": "target-instance-2", + "zone": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a", + "natPolicy": "NO_NAT", + "instance": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/instances/test-3", + "selfLink": "https://www.googleapis.com/compute/v1/projects/party/zones/us-central1-a/targetInstances/target-instance-2" + } + ] +} \ No newline at end of file