You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ad...@apache.org on 2014/11/07 17:08:04 UTC

[4/5] jclouds-labs-google git commit: Consolidate operation state management.

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RegionOperationApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RegionOperationApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RegionOperationApi.java
deleted file mode 100644
index 4bc0eac..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RegionOperationApi.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 static org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
-
-import java.util.Iterator;
-
-import javax.inject.Named;
-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 org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.googlecomputeengine.GoogleComputeEngineFallbacks.EmptyIteratorOnNotFoundOr404;
-import org.jclouds.googlecomputeengine.GoogleComputeEngineFallbacks.EmptyListPageOnNotFoundOr404;
-import org.jclouds.googlecomputeengine.domain.ListPage;
-import org.jclouds.googlecomputeengine.domain.Operation;
-import org.jclouds.googlecomputeengine.functions.internal.ParseRegionOperations;
-import org.jclouds.googlecomputeengine.options.ListOptions;
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.oauth.v2.config.OAuthScopes;
-import org.jclouds.oauth.v2.filters.OAuthAuthenticationFilter;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.ResponseParser;
-import org.jclouds.rest.annotations.SkipEncoding;
-import org.jclouds.rest.annotations.Transform;
-
-@SkipEncoding({'/', '='})
-@RequestFilters(OAuthAuthenticationFilter.class)
-@Path("/operations")
-@Consumes(APPLICATION_JSON)
-public interface RegionOperationApi {
-
-   /** Returns an operation by name or null if not found. */
-   @Named("RegionOperations:get")
-   @GET
-   @Path("/{operation}")
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @Fallback(NullOnNotFoundOr404.class)
-   @Nullable
-   Operation get(@PathParam("operation") String operation);
-
-   /** Deletes an operation by name. */
-   @Named("RegionOperations:delete")
-   @DELETE
-   @Path("/{operation}")
-   @OAuthScopes(COMPUTE_SCOPE)
-   @Fallback(VoidOnNotFoundOr404.class)
-   void delete(@PathParam("operation") String operation);
-
-   /**
-    * Retrieves the list of operation 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 token       marks the beginning of the next list page
-    * @param listOptions listing options
-    * @return a page of the list
-    */
-   @Named("RegionOperations:list")
-   @GET
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @ResponseParser(ParseRegionOperations.class)
-   @Fallback(EmptyListPageOnNotFoundOr404.class)
-   ListPage<Operation> listPage(@Nullable @QueryParam("pageToken") String token, ListOptions listOptions);
-
-   /**
-    * @see #list(org.jclouds.googlecomputeengine.options.ListOptions)
-    */
-   @Named("RegionOperations:list")
-   @GET
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @ResponseParser(ParseRegionOperations.class)
-   @Transform(ParseRegionOperations.ToIteratorOfListPage.class)
-   @Fallback(EmptyIteratorOnNotFoundOr404.class)
-   Iterator<ListPage<Operation>> list();
-
-   /**
-    * @see #list(org.jclouds.googlecomputeengine.options.ListOptions)
-    */
-   @Named("RegionOperations:list")
-   @GET
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @ResponseParser(ParseRegionOperations.class)
-   @Transform(ParseRegionOperations.ToIteratorOfListPage.class)
-   @Fallback(EmptyIteratorOnNotFoundOr404.class)
-   Iterator<ListPage<Operation>> list(ListOptions options);
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RouteApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RouteApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RouteApi.java
index 0919e6d..70594e2 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RouteApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RouteApi.java
@@ -91,7 +91,7 @@ public interface RouteApi {
    @POST
    @Consumes(APPLICATION_JSON)
    @Produces(APPLICATION_JSON)
-   @OAuthScopes({COMPUTE_SCOPE})
+   @OAuthScopes(COMPUTE_SCOPE)
    @MapBinder(RouteBinder.class)
    Operation createInNetwork(@PayloadParam("name") String name,
                              @PayloadParam("network") URI network,

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ZoneOperationApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ZoneOperationApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ZoneOperationApi.java
deleted file mode 100644
index e89a10b..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ZoneOperationApi.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 static org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
-
-import java.util.Iterator;
-
-import javax.inject.Named;
-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 org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.googlecomputeengine.GoogleComputeEngineFallbacks.EmptyIteratorOnNotFoundOr404;
-import org.jclouds.googlecomputeengine.GoogleComputeEngineFallbacks.EmptyListPageOnNotFoundOr404;
-import org.jclouds.googlecomputeengine.domain.ListPage;
-import org.jclouds.googlecomputeengine.domain.Operation;
-import org.jclouds.googlecomputeengine.functions.internal.ParseZoneOperations;
-import org.jclouds.googlecomputeengine.options.ListOptions;
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.oauth.v2.config.OAuthScopes;
-import org.jclouds.oauth.v2.filters.OAuthAuthenticationFilter;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.ResponseParser;
-import org.jclouds.rest.annotations.SkipEncoding;
-import org.jclouds.rest.annotations.Transform;
-
-@SkipEncoding({'/', '='})
-@RequestFilters(OAuthAuthenticationFilter.class)
-@Path("/operations")
-@Consumes(APPLICATION_JSON)
-public interface ZoneOperationApi {
-
-   /** Returns an operation by name or null if not found. */
-   @Named("ZoneOperations:get")
-   @GET
-   @Path("/{operation}")
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @Fallback(NullOnNotFoundOr404.class)
-   @Nullable
-   Operation get(@PathParam("operation") String operation);
-
-   /** Deletes an operation by name. */
-   @Named("ZoneOperations:delete")
-   @DELETE
-   @Path("/{operation}")
-   @OAuthScopes(COMPUTE_SCOPE)
-   @Fallback(VoidOnNotFoundOr404.class)
-   void delete(@PathParam("operation") String operation);
-
-   /**
-    * Retrieves the list of operation 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 token       marks the beginning of the next list page
-    * @param listOptions listing options
-    * @return a page of the list
-    */
-   @Named("ZoneOperations:list")
-   @GET
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @ResponseParser(ParseZoneOperations.class)
-   @Fallback(EmptyListPageOnNotFoundOr404.class)
-   ListPage<Operation> listPage(@Nullable @QueryParam("pageToken") String token, ListOptions listOptions);
-
-   /**
-    * @see #list(org.jclouds.googlecomputeengine.options.ListOptions)
-    */
-   @Named("ZoneOperations:list")
-   @GET
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @ResponseParser(ParseZoneOperations.class)
-   @Transform(ParseZoneOperations.ToIteratorOfListPage.class)
-   @Fallback(EmptyIteratorOnNotFoundOr404.class)
-   Iterator<ListPage<Operation>> list();
-
-   /**
-    * @see #list(org.jclouds.googlecomputeengine.options.ListOptions)
-    */
-   @Named("ZoneOperations:list")
-   @GET
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @ResponseParser(ParseZoneOperations.class)
-   @Transform(ParseZoneOperations.ToIteratorOfListPage.class)
-   @Fallback(EmptyIteratorOnNotFoundOr404.class)
-   Iterator<ListPage<Operation>> list(ListOptions options);
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithRegionToIteratorOfListPage.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithRegionToIteratorOfListPage.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithRegionToIteratorOfListPage.java
index eab19e6..54cbd5b 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithRegionToIteratorOfListPage.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithRegionToIteratorOfListPage.java
@@ -37,7 +37,7 @@ import com.google.common.collect.Iterators;
 abstract class BaseWithRegionToIteratorOfListPage<T, I extends BaseWithRegionToIteratorOfListPage<T, I>>
       implements Function<ListPage<T>, Iterator<ListPage<T>>>, InvocationContext<I> {
 
-   private GeneratedHttpRequest request;
+   GeneratedHttpRequest request;
 
    @Override public Iterator<ListPage<T>> apply(ListPage<T> input) {
       if (input.nextPageToken() == null)

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithZoneToIteratorOfListPage.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithZoneToIteratorOfListPage.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithZoneToIteratorOfListPage.java
index 16bc345..5c54f84 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithZoneToIteratorOfListPage.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/BaseWithZoneToIteratorOfListPage.java
@@ -37,7 +37,7 @@ import com.google.common.collect.Iterators;
 abstract class BaseWithZoneToIteratorOfListPage<T, I extends BaseWithZoneToIteratorOfListPage<T, I>>
       implements Function<ListPage<T>, Iterator<ListPage<T>>>, InvocationContext<I> {
 
-   private GeneratedHttpRequest request;
+   GeneratedHttpRequest request;
 
    @Override public Iterator<ListPage<T>> apply(ListPage<T> input) {
       if (input.nextPageToken() == null) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseGlobalOperations.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseGlobalOperations.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseGlobalOperations.java
index f45744f..738dacd 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseGlobalOperations.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseGlobalOperations.java
@@ -48,7 +48,7 @@ public final class ParseGlobalOperations extends ParseJson<ListPage<Operation>>
             final ListOptions options) {
          return new Function<String, ListPage<Operation>>() {
             @Override public ListPage<Operation> apply(String input) {
-               return api.getGlobalOperationApi(projectName).listPage(input, options);
+               return api.getOperationApi(projectName).listPage(input, options);
             }
          };
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseRegionOperations.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseRegionOperations.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseRegionOperations.java
index 8b19bd4..506f31d 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseRegionOperations.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseRegionOperations.java
@@ -16,6 +16,11 @@
  */
 package org.jclouds.googlecomputeengine.functions.internal;
 
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.collect.Iterables.tryFind;
+
+import java.util.Iterator;
+
 import javax.inject.Inject;
 
 import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
@@ -26,6 +31,8 @@ import org.jclouds.http.functions.ParseJson;
 import org.jclouds.json.Json;
 
 import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterators;
 import com.google.inject.TypeLiteral;
 
 public final class ParseRegionOperations extends ParseJson<ListPage<Operation>> {
@@ -38,6 +45,20 @@ public final class ParseRegionOperations extends ParseJson<ListPage<Operation>>
    public static class ToIteratorOfListPage
          extends BaseWithRegionToIteratorOfListPage<Operation, ToIteratorOfListPage> {
 
+      @Override public Iterator<ListPage<Operation>> apply(ListPage<Operation> input) {
+         if (input.nextPageToken() == null) {
+            return Iterators.singletonIterator(input);
+         }
+
+         String project = (String) request.getCaller().get().getArgs().get(0);
+         String region = (String) request.getInvocation().getArgs().get(0);
+
+         Optional<Object> listOptions = tryFind(request.getInvocation().getArgs(), instanceOf(ListOptions.class));
+
+         return new AdvancingIterator<Operation>(input,
+               fetchNextPage(project, region, (ListOptions) listOptions.orNull()));
+      }
+
       private final GoogleComputeEngineApi api;
 
       @Inject ToIteratorOfListPage(GoogleComputeEngineApi api) {
@@ -48,7 +69,7 @@ public final class ParseRegionOperations extends ParseJson<ListPage<Operation>>
             final String regionName, final ListOptions options) {
          return new Function<String, ListPage<Operation>>() {
             @Override public ListPage<Operation> apply(String input) {
-               return api.getRegionOperationApi(projectName, regionName).listPage(input, options);
+               return api.getOperationApi(projectName).listPageInRegion(regionName, input, options);
             }
          };
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseZoneOperations.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseZoneOperations.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseZoneOperations.java
index de2e6ec..9137642 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseZoneOperations.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/internal/ParseZoneOperations.java
@@ -16,6 +16,11 @@
  */
 package org.jclouds.googlecomputeengine.functions.internal;
 
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.collect.Iterables.tryFind;
+
+import java.util.Iterator;
+
 import javax.inject.Inject;
 
 import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
@@ -26,6 +31,8 @@ import org.jclouds.http.functions.ParseJson;
 import org.jclouds.json.Json;
 
 import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterators;
 import com.google.inject.TypeLiteral;
 
 public final class ParseZoneOperations extends ParseJson<ListPage<Operation>> {
@@ -43,12 +50,26 @@ public final class ParseZoneOperations extends ParseJson<ListPage<Operation>> {
          this.api = api;
       }
 
+      @Override public Iterator<ListPage<Operation>> apply(ListPage<Operation> input) {
+         if (input.nextPageToken() == null) {
+            return Iterators.singletonIterator(input);
+         }
+
+         String project = (String) request.getCaller().get().getArgs().get(0);
+         String zone = (String) request.getInvocation().getArgs().get(0);
+
+         Optional<Object> listOptions = tryFind(request.getInvocation().getArgs(), instanceOf(ListOptions.class));
+
+         return new AdvancingIterator<Operation>(input,
+               fetchNextPage(project, zone, (ListOptions) listOptions.orNull()));
+      }
+
       @Override protected Function<String, ListPage<Operation>> fetchNextPage(final String projectName,
             final String zoneName, final ListOptions options) {
          return new Function<String, ListPage<Operation>>() {
 
             @Override public ListPage<Operation> apply(String input) {
-               return api.getZoneOperationApi(projectName, zoneName).listPage(input, options);
+               return api.getOperationApi(projectName).listPageInZone(zoneName, input, options);
             }
          };
       }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/GlobalOperationDonePredicate.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/GlobalOperationDonePredicate.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/GlobalOperationDonePredicate.java
deleted file mode 100644
index 10fb995..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/GlobalOperationDonePredicate.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.predicates;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
-import org.jclouds.googlecomputeengine.config.UserProject;
-import org.jclouds.googlecomputeengine.domain.Operation;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.inject.Inject;
-
-public final class GlobalOperationDonePredicate implements Predicate<AtomicReference<Operation>> {
-
-   private final GoogleComputeEngineApi api;
-   private final Supplier<String> project;
-
-   @Inject GlobalOperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project) {
-      this.api = api;
-      this.project = project;
-   }
-
-   @Override public boolean apply(AtomicReference<Operation> input) {
-      checkNotNull(input, "input");
-      Operation current = api.getGlobalOperationApi(project.get()).get(input.get().name());
-      switch (current.status()) {
-         case DONE:
-            input.set(current);
-            return true;
-         case PENDING:
-         case RUNNING:
-         default:
-            return false;
-      }
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/InstancePredicates.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/InstancePredicates.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/InstancePredicates.java
deleted file mode 100644
index e8d6535..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/InstancePredicates.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.predicates;
-
-import org.jclouds.googlecomputeengine.domain.templates.InstanceTemplate.PersistentDisk;
-
-import com.google.common.base.Predicate;
-
-public class InstancePredicates {
-
-   public static Predicate<PersistentDisk> isBootDisk() {
-      return new Predicate<PersistentDisk>() {
-         @Override
-         public boolean apply(PersistentDisk input) {
-            return input.boot();
-         }
-      };
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicates.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicates.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicates.java
deleted file mode 100644
index c63db43..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicates.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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.predicates;
-
-import static com.google.common.collect.Sets.intersection;
-
-import java.util.List;
-
-import org.jclouds.googlecomputeengine.domain.Firewall;
-import org.jclouds.googlecomputeengine.domain.Firewall.Rule;
-import org.jclouds.net.domain.IpPermission;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-public final class NetworkFirewallPredicates {
-
-   public static Predicate<Firewall> hasPortRange(final String protocol, final int fromPort, final int toPort) {
-      return new Predicate<Firewall>() {
-         @Override public boolean apply(Firewall fw) {
-            for (Rule rule : fw.allowed()) {
-               if (!rule.ipProtocol().equals(protocol)) {
-                  continue;
-               }
-               if (rule.ports() == null || rule.ports().isEmpty()) {
-                  return true;
-               }
-               for (String range : rule.ports()) {
-                  if (range.indexOf('-') != -1) {
-                     if (inRange(range, fromPort, toPort)) {
-                        return true;
-                     }
-                  }
-               }
-            }
-            return false;
-         }
-      };
-   }
-
-   private static boolean inRange(String range, int fromPort, int toPort) {
-      List<String> ports = Splitter.on('-').splitToList(range);
-      return fromPort >= Integer.valueOf(ports.get(0)) && toPort <= Integer.valueOf(ports.get(1));
-   }
-
-   public static Predicate<Firewall> hasSourceTag(final String sourceTag) {
-      return new Predicate<Firewall>() {
-         @Override public boolean apply(Firewall input) {
-            return input.sourceTags().contains(sourceTag);
-         }
-      };
-   }
-
-   public static Predicate<Firewall> hasSourceRange(final String sourceRange) {
-      return new Predicate<Firewall>() {
-         @Override  public boolean apply(Firewall input) {
-            return input.sourceRanges().contains(sourceRange);
-         }
-      };
-   }
-
-   public static Predicate<Firewall> equalsIpPermission(final IpPermission permission) {
-      return new Predicate<Firewall>() {
-         @Override public boolean apply(Firewall input) {
-            return Iterables.elementsEqual(permission.getGroupIds(), input.sourceTags())
-                      && Iterables.elementsEqual(permission.getCidrBlocks(), input.sourceRanges())
-                      && (input.allowed().size() == 1
-                             && ruleEqualsIpPermission(permission).apply(Iterables.getOnlyElement(input.allowed())));
-         }
-      };
-   }
-
-   public static Predicate<Firewall> providesIpPermission(final IpPermission permission) {
-      return new Predicate<Firewall>() {
-         @Override  public boolean apply(Firewall input) {
-            boolean groupsMatchTags =
-                  (permission.getGroupIds().isEmpty() && input.sourceTags().isEmpty()) || !intersection(
-                        permission.getGroupIds(), ImmutableSet.copyOf(input.sourceTags())).isEmpty();
-            boolean cidrsMatchRanges =
-                  (permission.getCidrBlocks().isEmpty() && input.sourceRanges().isEmpty()) || !intersection(
-                        permission.getCidrBlocks(), ImmutableSet.copyOf(input.sourceRanges())).isEmpty();
-            boolean firewallHasPorts = hasPortRange(permission.getIpProtocol().value().toLowerCase(),
-                        permission.getFromPort(), permission.getToPort()).apply(input);
-            return groupsMatchTags && cidrsMatchRanges && firewallHasPorts;
-         }
-      };
-   }
-
-   private static Predicate<Firewall.Rule> ruleEqualsIpPermission(final IpPermission permission) {
-      return new Predicate<Rule>() {
-         @Override public boolean apply(Firewall.Rule input) {
-            if (!permission.getIpProtocol().value().toLowerCase().equals(input.ipProtocol())) {
-               return false;
-            }
-            if (input.ports() == null
-                  || input.ports().isEmpty() && permission.getFromPort() == 0 && permission.getToPort() == 0) {
-               return true;
-            } else if (input.ports().size() == 1) {
-               String port = Iterables.getOnlyElement(input.ports());
-               if (permission.getFromPort() == permission.getToPort()) {
-                  return port.equals(String.valueOf(permission.getFromPort()));
-               }
-               return port.equals(permission.getFromPort() + "-" + permission.getToPort());
-            }
-            return false;
-         }
-      };
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/RegionOperationDonePredicate.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/RegionOperationDonePredicate.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/RegionOperationDonePredicate.java
deleted file mode 100644
index 65c0723..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/RegionOperationDonePredicate.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.predicates;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.inject.Inject;
-
-import org.jclouds.collect.Memoized;
-import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
-import org.jclouds.googlecomputeengine.config.UserProject;
-import org.jclouds.googlecomputeengine.domain.Operation;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-
-public final class RegionOperationDonePredicate implements Predicate<AtomicReference<Operation>> {
-   private final GoogleComputeEngineApi api;
-   private final Supplier<String> project;
-   private final Supplier<Map<URI, String>> selfLinkToName;
-
-   @Inject RegionOperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project,
-         @Memoized Supplier<Map<URI, String>> selfLinkToName) {
-      this.api = api;
-      this.project = project;
-      this.selfLinkToName = selfLinkToName;
-   }
-
-   @Override public boolean apply(AtomicReference<Operation> input) {
-      checkNotNull(input.get(), "input");
-      URI region = checkNotNull(input.get().region(), "region of %s", input.get());
-      String locationId = checkNotNull(selfLinkToName.get().get(region), "location of %s", region);
-      Operation current = api.getRegionOperationApi(project.get(), locationId).get(input.get().name());
-      switch (current.status()) {
-         case DONE:
-            input.set(current);
-            return true;
-         case PENDING:
-         case RUNNING:
-         default:
-            return false;
-      }
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/ZoneOperationDonePredicate.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/ZoneOperationDonePredicate.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/ZoneOperationDonePredicate.java
deleted file mode 100644
index 0081d30..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/ZoneOperationDonePredicate.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.predicates;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.jclouds.collect.Memoized;
-import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
-import org.jclouds.googlecomputeengine.config.UserProject;
-import org.jclouds.googlecomputeengine.domain.Operation;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.inject.Inject;
-
-/**
- * Tests that a Zone Operation is done, returning the completed Operation when it is.
- */
-public final class ZoneOperationDonePredicate implements Predicate<AtomicReference<Operation>> {
-
-   private final GoogleComputeEngineApi api;
-   private final Supplier<String> project;
-   private final Supplier<Map<URI, String>> selfLinkToName;
-
-   @Inject ZoneOperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project,
-         @Memoized Supplier<Map<URI, String>> selfLinkToName) {
-      this.api = api;
-      this.project = project;
-      this.selfLinkToName = selfLinkToName;
-   }
-
-   @Override public boolean apply(AtomicReference<Operation> input) {
-      checkNotNull(input.get(), "input");
-      URI zone = checkNotNull(input.get().zone(), "zone of %s", input.get());
-      String locationId = checkNotNull(selfLinkToName.get().get(zone), "location of %s", zone);
-      Operation current = api.getZoneOperationApi(project.get(), locationId).get(input.get().name());
-      switch (current.status()) {
-         case DONE:
-            input.set(current);
-            return true;
-         case PENDING:
-         case RUNNING:
-         default:
-            return false;
-      }
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceExpectTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceExpectTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceExpectTest.java
index 3018c1e..6549823 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceExpectTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineServiceExpectTest.java
@@ -25,8 +25,6 @@ import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_B
 import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_PROJECTS;
 import static org.jclouds.googlecomputeengine.domain.Instance.Status.RUNNING;
 import static org.jclouds.googlecomputeengine.domain.Instance.Status.TERMINATED;
-import static org.jclouds.googlecomputeengine.features.GlobalOperationApiExpectTest.GET_GLOBAL_OPERATION_REQUEST;
-import static org.jclouds.googlecomputeengine.features.GlobalOperationApiExpectTest.GET_GLOBAL_OPERATION_RESPONSE;
 import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_CENTOS_IMAGES_REQUEST;
 import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_CENTOS_IMAGES_RESPONSE;
 import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_DEBIAN_IMAGES_REQUEST;
@@ -45,8 +43,6 @@ import static org.jclouds.googlecomputeengine.features.NetworkApiExpectTest.GET_
 import static org.jclouds.googlecomputeengine.features.ProjectApiExpectTest.GET_PROJECT_REQUEST;
 import static org.jclouds.googlecomputeengine.features.ProjectApiExpectTest.GET_PROJECT_RESPONSE;
 import static org.jclouds.googlecomputeengine.features.RegionApiExpectTest.LIST_REGIONS_REQ;
-import static org.jclouds.googlecomputeengine.features.ZoneOperationApiExpectTest.GET_ZONE_OPERATION_REQUEST;
-import static org.jclouds.googlecomputeengine.features.ZoneOperationApiExpectTest.GET_ZONE_OPERATION_RESPONSE;
 import static org.jclouds.util.Strings2.toStringAndClose;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -77,6 +73,17 @@ import com.google.common.collect.ImmutableSet;
 
 @Test(groups = "unit", testName = "GoogleComputeEngineServiceExpectTest")
 public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngineServiceExpectTest {
+   private static final String OPERATIONS_URL_PREFIX = BASE_URL + "/myproject/zones/us-central1-a/operations";
+
+   private static final HttpRequest GET_ZONE_OPERATION_REQUEST = HttpRequest
+           .builder()
+           .method("GET")
+           .endpoint(OPERATIONS_URL_PREFIX + "/operation-1354084865060-4cf88735faeb8-bbbb12cb")
+           .addHeader("Accept", "application/json")
+           .addHeader("Authorization", "Bearer " + TOKEN).build();
+
+   private static final HttpResponse GET_ZONE_OPERATION_RESPONSE = HttpResponse.builder().statusCode(200)
+           .payload(staticPayloadFromResource("/zone_operation.json")).build();
 
    private HttpRequest INSERT_NETWORK_REQUEST = HttpRequest
            .builder()
@@ -339,9 +346,9 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
               .add(getNetworkRequest)
               .add(listFirewallsRequest)
               .add(deleteFirewallRequest)
-              .add(GET_GLOBAL_OPERATION_REQUEST)
+              .add(GET_ZONE_OPERATION_REQUEST)
               .add(deleteNetworkReqquest)
-              .add(GET_GLOBAL_OPERATION_REQUEST)
+              .add(GET_ZONE_OPERATION_REQUEST)
               .build();
 
       List<HttpResponse> orderedResponses = ImmutableList.<HttpResponse>builder()
@@ -365,9 +372,9 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
               .add(getNetworkResponse)
               .add(listFirewallsResponse)
               .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_GLOBAL_OPERATION_RESPONSE)
+              .add(GET_ZONE_OPERATION_RESPONSE)
               .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_GLOBAL_OPERATION_RESPONSE)
+              .add(GET_ZONE_OPERATION_RESPONSE)
               .build();
 
       ComputeService client = orderedRequestsSendResponses(orderedRequests, orderedResponses);
@@ -375,7 +382,6 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
    }
 
    public void listAssignableLocations() throws Exception {
-
       ImmutableMap<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.
               <HttpRequest, HttpResponse>builder()
               .put(requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE)
@@ -478,11 +484,11 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
               .add(GET_NETWORK_REQUEST)
               .add(requestForScopes(COMPUTE_SCOPE))
               .add(INSERT_NETWORK_REQUEST)
-              .add(GET_GLOBAL_OPERATION_REQUEST)
+              .add(GET_ZONE_OPERATION_REQUEST)
               .add(GET_NETWORK_REQUEST)
               .add(getFirewallRequest)
               .add(insertFirewallRequest)
-              .add(GET_GLOBAL_OPERATION_REQUEST)
+              .add(GET_ZONE_OPERATION_REQUEST)
               .add(LIST_INSTANCES_REQUEST)
               .add(createDiskRequestForInstance("test-1"))
               .add(GET_ZONE_OPERATION_REQUEST)
@@ -512,11 +518,11 @@ public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngin
               .add(HttpResponse.builder().statusCode(404).build())
               .add(TOKEN_RESPONSE)
               .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_GLOBAL_OPERATION_RESPONSE)
+              .add(GET_ZONE_OPERATION_RESPONSE)
               .add(GET_NETWORK_RESPONSE)
               .add(HttpResponse.builder().statusCode(404).build())
               .add(SUCCESSFUL_OPERATION_RESPONSE)
-              .add(GET_GLOBAL_OPERATION_RESPONSE)
+              .add(GET_ZONE_OPERATION_RESPONSE)
               .add(LIST_INSTANCES_RESPONSE)
               .add(SUCCESSFUL_OPERATION_RESPONSE)
               .add(GET_ZONE_OPERATION_RESPONSE)

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java
index 101758f..dcbd1bc 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/CreateNetworkIfNeededTest.java
@@ -26,16 +26,16 @@ import java.net.URI;
 
 import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
 import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
+import org.jclouds.googlecomputeengine.compute.predicates.AtomicOperationDone;
 import org.jclouds.googlecomputeengine.config.UserProject;
 import org.jclouds.googlecomputeengine.domain.Network;
 import org.jclouds.googlecomputeengine.domain.Operation;
-import org.jclouds.googlecomputeengine.features.GlobalOperationApi;
 import org.jclouds.googlecomputeengine.features.NetworkApi;
 import org.jclouds.googlecomputeengine.parse.ParseGlobalOperationTest;
-import org.jclouds.googlecomputeengine.predicates.GlobalOperationDonePredicate;
 import org.testng.annotations.Test;
 
 import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Provides;
@@ -48,7 +48,7 @@ public class CreateNetworkIfNeededTest {
    public void testApply() {
       GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
       NetworkApi nwApi = createMock(NetworkApi.class);
-      GlobalOperationApi globalApi = createMock(GlobalOperationApi.class);
+      ResourceFunctions resources = createMock(ResourceFunctions.class);
 
       Network network = Network.create( //
             "abcd", // id
@@ -61,38 +61,32 @@ public class CreateNetworkIfNeededTest {
 
       Operation createOp = new ParseGlobalOperationTest().expected();
 
-      Supplier<String> userProject = new Supplier<String>() {
-         @Override
-         public String get() {
-            return "myproject";
-         }
-      };
+      Supplier<String> userProject = Suppliers.ofInstance("myproject");
 
       expect(api.getNetworkApi(userProject.get())).andReturn(nwApi).atLeastOnce();
-      expect(api.getGlobalOperationApi(userProject.get())).andReturn(globalApi).atLeastOnce();
 
       expect(nwApi.createInIPv4Range("this-network", "0.0.0.0/0")) .andReturn(createOp);
-      expect(globalApi.get(createOp.name())).andReturn(createOp);
+      expect(resources.operation(createOp.selfLink())).andReturn(createOp);
       expect(nwApi.get("this-network")).andReturn(null);
       expect(nwApi.get("this-network")).andReturn(network);
 
-      replay(api, nwApi, globalApi);
+      replay(api, nwApi, resources);
 
       NetworkAndAddressRange input = NetworkAndAddressRange.create("this-network", "0.0.0.0/0", null);
 
-      GlobalOperationDonePredicate pred = globalOperationDonePredicate(api, userProject);
+      AtomicOperationDone pred = atomicOperationDone(api, resources);
 
-      CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
+      CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred);
 
       assertEquals(creator.apply(input), network);
 
-      verify(api, nwApi, globalApi);
+      verify(api, nwApi, resources);
    }
 
    public void testApplyWithGateway() {
       GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
       NetworkApi nwApi = createMock(NetworkApi.class);
-      GlobalOperationApi globalApi = createMock(GlobalOperationApi.class);
+      ResourceFunctions resources = createMock(ResourceFunctions.class);
 
       Network network = Network.create( //
             "abcd", // id
@@ -105,44 +99,39 @@ public class CreateNetworkIfNeededTest {
 
       Operation createOp = new ParseGlobalOperationTest().expected();
 
-      Supplier<String> userProject = new Supplier<String>() {
-         @Override
-         public String get() {
-            return "myproject";
-         }
-      };
+      Supplier<String> userProject = Suppliers.ofInstance("myproject");
 
       expect(api.getNetworkApi(userProject.get())).andReturn(nwApi).atLeastOnce();
-      expect(api.getGlobalOperationApi(userProject.get())).andReturn(globalApi).atLeastOnce();
 
       expect(nwApi.createInIPv4RangeWithGateway("this-network", "0.0.0.0/0", "1.2.3.4")).andReturn(createOp);
-      expect(globalApi.get(createOp.name())).andReturn(createOp);
+      expect(resources.operation(createOp.selfLink())).andReturn(createOp);
       expect(nwApi.get("this-network")).andReturn(null);
       expect(nwApi.get("this-network")).andReturn(network);
 
-      replay(api, nwApi, globalApi);
+      replay(api, nwApi, resources);
 
       NetworkAndAddressRange input = NetworkAndAddressRange.create("this-network", "0.0.0.0/0", "1.2.3.4");
 
-      GlobalOperationDonePredicate pred = globalOperationDonePredicate(api, userProject);
+      AtomicOperationDone pred = atomicOperationDone(api, resources);
 
-      CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
+      CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred);
 
       assertEquals(creator.apply(input), network);
 
-      verify(api, nwApi, globalApi);
+      verify(api, nwApi, resources);
    }
 
-   private GlobalOperationDonePredicate globalOperationDonePredicate(final GoogleComputeEngineApi api,
-         final Supplier<String> userProject) {
+   private AtomicOperationDone atomicOperationDone(final GoogleComputeEngineApi api,
+         final ResourceFunctions resources) {
       return Guice.createInjector(new AbstractModule() { // Rather than opening ctor public
          @Override protected void configure() {
             bind(GoogleComputeEngineApi.class).toInstance(api);
+            bind(ResourceFunctions.class).toInstance(resources);
          }
 
          @Provides @UserProject Supplier<String> project() {
-            return userProject;
+            return Suppliers.ofInstance("myproject");
          }
-      }).getInstance(GlobalOperationDonePredicate.class);
+      }).getInstance(AtomicOperationDone.class);
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java
index 3037a5e..068446f 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FindNetworkOrCreateTest.java
@@ -23,27 +23,29 @@ import static org.easymock.EasyMock.verify;
 import static org.testng.Assert.assertEquals;
 
 import java.net.URI;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
 import org.jclouds.googlecomputeengine.compute.domain.NetworkAndAddressRange;
-import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.compute.predicates.AtomicOperationDone;
 import org.jclouds.googlecomputeengine.domain.Network;
 import org.jclouds.googlecomputeengine.domain.Operation;
-import org.jclouds.googlecomputeengine.features.GlobalOperationApi;
 import org.jclouds.googlecomputeengine.features.NetworkApi;
 import org.jclouds.googlecomputeengine.parse.ParseGlobalOperationTest;
-import org.jclouds.googlecomputeengine.predicates.GlobalOperationDonePredicate;
 import org.testng.annotations.Test;
 
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
 import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.LoadingCache;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
-import com.google.inject.Provides;
 
 @Test
 public class FindNetworkOrCreateTest {
+   private static final Supplier<String> USER_PROJECT = Suppliers.ofInstance("myproject");
    private static final String BASE_URL = "https://www.googleapis.com/compute/v1/projects";
    private static final Network NETWORK = Network.create( //
          "abcd", // id
@@ -58,14 +60,7 @@ public class FindNetworkOrCreateTest {
       GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
       NetworkApi nwApi = createMock(NetworkApi.class);
 
-      Supplier<String> userProject = new Supplier<String>() {
-         @Override
-         public String get() {
-            return "myproject";
-         }
-      };
-
-      expect(api.getNetworkApi(userProject.get())).andReturn(nwApi).atLeastOnce();
+      expect(api.getNetworkApi(USER_PROJECT.get())).andReturn(nwApi).atLeastOnce();
 
       expect(nwApi.get("this-network")).andReturn(NETWORK);
 
@@ -73,11 +68,11 @@ public class FindNetworkOrCreateTest {
 
       NetworkAndAddressRange input = NetworkAndAddressRange.create("this-network", "0.0.0.0/0", null);
 
-      GlobalOperationDonePredicate pred = globalOperationDonePredicate(api, userProject);
+      Predicate<AtomicReference<Operation>> operationDone = Predicates.alwaysFalse(); // No op should be created!
 
-      CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
+      CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, USER_PROJECT, operationDone);
 
-      FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator, userProject);
+      FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator, USER_PROJECT);
 
       LoadingCache<NetworkAndAddressRange, Network> cache = CacheBuilder.newBuilder().build(loader);
 
@@ -92,36 +87,28 @@ public class FindNetworkOrCreateTest {
    public void testLoadNew() {
       GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
       NetworkApi nwApi = createMock(NetworkApi.class);
-      GlobalOperationApi globalApi = createMock(GlobalOperationApi.class);
+      ResourceFunctions resources = createMock(ResourceFunctions.class);
 
       Operation createOp = new ParseGlobalOperationTest().expected();
 
-      Supplier<String> userProject = new Supplier<String>() {
-         @Override
-         public String get() {
-            return "myproject";
-         }
-      };
-
-      expect(api.getNetworkApi(userProject.get())).andReturn(nwApi).atLeastOnce();
-      expect(api.getGlobalOperationApi(userProject.get())).andReturn(globalApi).atLeastOnce();
+      expect(api.getNetworkApi(USER_PROJECT.get())).andReturn(nwApi).atLeastOnce();
 
       expect(nwApi.createInIPv4Range("this-network", "0.0.0.0/0")).andReturn(createOp);
-      expect(globalApi.get(createOp.name())).andReturn(createOp);
+      expect(resources.operation(createOp.selfLink())).andReturn(createOp);
       // pre-creation
       expect(nwApi.get("this-network")).andReturn(null).times(2);
       // post-creation
       expect(nwApi.get("this-network")).andReturn(NETWORK);
 
-      replay(api, nwApi, globalApi);
+      replay(api, nwApi, resources);
 
       NetworkAndAddressRange input = NetworkAndAddressRange.create("this-network", "0.0.0.0/0", null);
 
-      GlobalOperationDonePredicate pred = globalOperationDonePredicate(api, userProject);
+      AtomicOperationDone pred = atomicOperationDone(resources);
 
-      CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
+      CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, USER_PROJECT, pred);
 
-      FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator, userProject);
+      FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator, USER_PROJECT);
 
       LoadingCache<NetworkAndAddressRange, Network> cache = CacheBuilder.newBuilder().build(loader);
 
@@ -130,20 +117,15 @@ public class FindNetworkOrCreateTest {
       // Second call is to ensure we only need to make the API calls once.
       assertEquals(cache.getUnchecked(input), NETWORK);
 
-      verify(api, nwApi, globalApi);
+      verify(api, nwApi, resources);
    }
 
-   private GlobalOperationDonePredicate globalOperationDonePredicate(final GoogleComputeEngineApi api,
-         final Supplier<String> userProject) {
+   private AtomicOperationDone atomicOperationDone(final ResourceFunctions resources) {
       return Guice.createInjector(new AbstractModule() { // Rather than opening ctor public
          @Override protected void configure() {
-            bind(GoogleComputeEngineApi.class).toInstance(api);
-         }
-
-         @Provides @UserProject Supplier<String> project() {
-            return userProject;
+            bind(ResourceFunctions.class).toInstance(resources);
          }
-      }).getInstance(GlobalOperationDonePredicate.class);
+      }).getInstance(AtomicOperationDone.class);
    }
 }
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java
index 959ce15..d4df1e5 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImageTest.java
@@ -27,7 +27,7 @@ import org.testng.annotations.Test;
 
 @Test(groups = "unit", testName = "GoogleComputeEngineImageToImageTest")
 public class GoogleComputeEngineImageToImageTest {
-   public void testArbitratyImageName() {
+   public void testArbitraryImageName() {
       GoogleComputeEngineImageToImage imageToImage = new GoogleComputeEngineImageToImage();
       Image image = image("arbitratyname");
       org.jclouds.compute.domain.Image transformed = imageToImage.apply(image);

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
index 891a5a9..933487f 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
@@ -39,6 +39,7 @@ import org.testng.annotations.Test;
 
 import com.google.common.base.Predicates;
 import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 
@@ -46,12 +47,7 @@ public class NetworkToSecurityGroupTest {
 
    @Test
    public void testApply() {
-      Supplier<String> projectSupplier = new Supplier<String>() {
-         @Override
-         public String get() {
-            return "myproject";
-         }
-      };
+      Supplier<String> projectSupplier = Suppliers.ofInstance("myproject");
 
       FirewallToIpPermission fwToPerm = new FirewallToIpPermission();
 

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodesTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodesTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodesTest.java
index cb48943..c15dacc 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodesTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodesTest.java
@@ -36,6 +36,8 @@ import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
 
 public class OrphanedGroupsFromDeadNodesTest {
 
@@ -67,8 +69,8 @@ public class OrphanedGroupsFromDeadNodesTest {
 
       replay(mock);
 
-      OrphanedGroupsFromDeadNodes orphanedGroupsFromDeadNodes = new OrphanedGroupsFromDeadNodes(new
-              AllNodesInGroupTerminated(mock));
+      OrphanedGroupsFromDeadNodes orphanedGroupsFromDeadNodes = new OrphanedGroupsFromDeadNodes(
+              allNodesInGroupTerminated(mock));
 
       Set<String> orphanedGroups = orphanedGroupsFromDeadNodes.apply(allDeadNodes);
 
@@ -96,8 +98,8 @@ public class OrphanedGroupsFromDeadNodesTest {
 
       replay(mock);
 
-      OrphanedGroupsFromDeadNodes orphanedGroupsFromDeadNodes = new OrphanedGroupsFromDeadNodes(new
-              AllNodesInGroupTerminated(mock));
+      OrphanedGroupsFromDeadNodes orphanedGroupsFromDeadNodes = new OrphanedGroupsFromDeadNodes(
+            allNodesInGroupTerminated(mock));
 
       Set<String> orphanedGroups = orphanedGroupsFromDeadNodes.apply(allDeadNodes);
 
@@ -125,12 +127,20 @@ public class OrphanedGroupsFromDeadNodesTest {
 
       replay(mock);
 
-      OrphanedGroupsFromDeadNodes orphanedGroupsFromDeadNodes = new OrphanedGroupsFromDeadNodes(new
-              AllNodesInGroupTerminated(mock));
+      OrphanedGroupsFromDeadNodes orphanedGroupsFromDeadNodes = new OrphanedGroupsFromDeadNodes(
+              allNodesInGroupTerminated(mock));
 
       Set<String> orphanedGroups = orphanedGroupsFromDeadNodes.apply(allDeadNodes);
 
       assertSame(orphanedGroups.size(), 1);
       assertTrue(orphanedGroups.contains("1"));
    }
+
+   private Predicate<String> allNodesInGroupTerminated(final ComputeService mock) {
+      return Guice.createInjector(new AbstractModule() {
+         @Override protected void configure() {
+            bind(ComputeService.class).toInstance(mock);
+         }
+      }).getInstance(AllNodesInGroupTerminated.class); // rather than opening ctor.
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiLiveTest.java
index f076687..d5f71a8 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiLiveTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/AddressApiLiveTest.java
@@ -30,7 +30,6 @@ import org.testng.annotations.Test;
 public class AddressApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    private static final String ADDRESS_NAME = "address-api-live-test-address";
-   private static final int TIME_WAIT = 30;
 
    private AddressApi api() {
       return api.getAddressApi(userProject.get(), DEFAULT_REGION_NAME);
@@ -38,8 +37,7 @@ public class AddressApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    @Test(groups = "live")
    public void testInsertAddress() {
-
-      assertRegionOperationDoneSucessfully(api().create(ADDRESS_NAME), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().create(ADDRESS_NAME));
    }
 
    @Test(groups = "live", dependsOnMethods = "testInsertAddress")
@@ -51,14 +49,12 @@ public class AddressApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    @Test(groups = "live", dependsOnMethods = "testGetAddress")
    public void testListAddress() {
-
       Iterator<ListPage<Address>> addresses = api().list(filter("name eq " + ADDRESS_NAME));
       assertEquals(addresses.next().size(), 1);
    }
 
    @Test(groups = "live", dependsOnMethods = "testListAddress")
    public void testDeleteAddress() {
-
-      assertRegionOperationDoneSucessfully(api().delete(ADDRESS_NAME), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().delete(ADDRESS_NAME));
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java
index ad771d9..8b61648 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/DiskApiLiveTest.java
@@ -34,7 +34,6 @@ public class DiskApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    public static final String DISK_NAME = "disk-api-live-test-disk";
    public static final String SSD_DISK_NAME = "disk-api-live-test-disk-ssd";
-   public static final int TIME_WAIT = 30;
    public static final int sizeGb = 1;
 
    private DiskApi api() {
@@ -43,7 +42,7 @@ public class DiskApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    @Test(groups = "live")
    public void testInsertDisk() {
-      assertZoneOperationDoneSuccessfully(api().create(DISK_NAME, sizeGb), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().create(DISK_NAME, sizeGb));
    }
 
    @Test(groups = "live", dependsOnMethods = "testInsertDisk")
@@ -66,7 +65,7 @@ public class DiskApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    @Test(groups = "live", dependsOnMethods = "testListDisk")
    public void testDeleteDisk() {
-      assertZoneOperationDoneSuccessfully(api().delete(DISK_NAME), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().delete(DISK_NAME));
    }
 
    private void assertDiskEquals(Disk result) {
@@ -79,7 +78,7 @@ public class DiskApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
    public void testInsertSSDDisk() {
       URI diskType = getDiskTypeUrl(userProject.get(), DEFAULT_ZONE_NAME, "pd-ssd");
       DiskCreationOptions diskCreationOptions = new DiskCreationOptions().type(diskType);
-      assertZoneOperationDoneSuccessfully(api().create(SSD_DISK_NAME, sizeGb, diskCreationOptions), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().create(SSD_DISK_NAME, sizeGb, diskCreationOptions));
    }
 
    @Test(groups = "live", dependsOnMethods = "testInsertSSDDisk")
@@ -91,7 +90,7 @@ public class DiskApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    @Test(groups = "live", dependsOnMethods = "testGetSSDDisk")
    public void testDeleteSSDDisk() {
-      assertZoneOperationDoneSuccessfully(api().delete(SSD_DISK_NAME), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().delete(SSD_DISK_NAME));
    }
 
    private void assertSSDDiskEquals(Disk result) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java
index 6cc6ec7..0d7371a 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java
@@ -22,7 +22,6 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 
 import java.util.Iterator;
-import java.util.List;
 
 import org.jclouds.googlecomputeengine.domain.Firewall;
 import org.jclouds.googlecomputeengine.domain.ListPage;
@@ -38,7 +37,6 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
    private static final String FIREWALL_NAME = "firewall-api-live-test-firewall";
    private static final String FIREWALL_NETWORK_NAME = "firewall-api-live-test-network";
    private static final String IPV4_RANGE = "10.0.0.0/8";
-   private static final int TIME_WAIT = 30;
 
    private FirewallApi api() {
       return api.getFirewallApi(userProject.get());
@@ -46,10 +44,9 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    @Test(groups = "live")
    public void testInsertFirewall() {
-
       // need to insert the network first
-      assertGlobalOperationDoneSucessfully(api.getNetworkApi(userProject.get()).createInIPv4Range
-              (FIREWALL_NETWORK_NAME, IPV4_RANGE), TIME_WAIT);
+      assertOperationDoneSuccessfully(
+            api.getNetworkApi(userProject.get()).createInIPv4Range(FIREWALL_NETWORK_NAME, IPV4_RANGE));
 
       FirewallOptions firewall = new FirewallOptions()
               .addAllowedRule(Firewall.Rule.create("tcp", ImmutableList.of("22")))
@@ -57,13 +54,12 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
               .addSourceTag("tag1")
               .addTargetTag("tag2");
 
-      assertGlobalOperationDoneSucessfully(api().createInNetwork(FIREWALL_NAME, getNetworkUrl(userProject.get(),
-              FIREWALL_NETWORK_NAME), firewall), TIME_WAIT);
+      assertOperationDoneSuccessfully(
+            api().createInNetwork(FIREWALL_NAME, getNetworkUrl(userProject.get(), FIREWALL_NETWORK_NAME), firewall));
    }
 
    @Test(groups = "live", dependsOnMethods = "testInsertFirewall")
    public void testUpdateFirewall() {
-
       FirewallOptions firewall = new FirewallOptions()
               .name(FIREWALL_NAME)
               .network(getNetworkUrl(userProject.get(), FIREWALL_NETWORK_NAME))
@@ -72,12 +68,11 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
               .addTargetTag("tag2")
               .allowedRules(ImmutableList.of(Firewall.Rule.create("tcp", ImmutableList.of("23"))));
 
-      assertGlobalOperationDoneSucessfully(api().update(FIREWALL_NAME, firewall), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().update(FIREWALL_NAME, firewall));
    }
 
    @Test(groups = "live", dependsOnMethods = "testUpdateFirewall")
    public void testPatchFirewall() {
-
       FirewallOptions firewall = new FirewallOptions()
               .name(FIREWALL_NAME)
               .network(getNetworkUrl(userProject.get(), FIREWALL_NETWORK_NAME))
@@ -87,12 +82,11 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
               .addSourceTag("tag1")
               .addTargetTag("tag2");
 
-      assertGlobalOperationDoneSucessfully(api().update(FIREWALL_NAME, firewall), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().update(FIREWALL_NAME, firewall));
    }
 
    @Test(groups = "live", dependsOnMethods = "testPatchFirewall")
    public void testGetFirewall() {
-
       FirewallOptions patchedFirewall = new FirewallOptions()
               .name(FIREWALL_NAME)
               .network(getNetworkUrl(userProject.get(), FIREWALL_NETWORK_NAME))
@@ -109,20 +103,15 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
 
    @Test(groups = "live", dependsOnMethods = "testGetFirewall")
    public void testListFirewall() {
-
       Iterator<ListPage<Firewall>> firewalls = api().list(filter("name eq " + FIREWALL_NAME));
 
-      List<Firewall> firewallsAsList = firewalls.next();
-
-      assertEquals(firewallsAsList.size(), 1);
+      assertEquals(firewalls.next().size(), 1);
    }
 
    @Test(groups = "live", dependsOnMethods = "testListFirewall")
    public void testDeleteFirewall() {
-
-      assertGlobalOperationDoneSucessfully(api().delete(FIREWALL_NAME), TIME_WAIT);
-      assertGlobalOperationDoneSucessfully(api.getNetworkApi(userProject.get()).delete
-              (FIREWALL_NETWORK_NAME), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().delete(FIREWALL_NAME));
+      assertOperationDoneSuccessfully(api.getNetworkApi(userProject.get()).delete(FIREWALL_NETWORK_NAME));
    }
 
    private void assertFirewallEquals(Firewall result, FirewallOptions expected) {

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApiLiveTest.java
index 9b361ee..20b2334 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApiLiveTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/ForwardingRuleApiLiveTest.java
@@ -38,7 +38,6 @@ public class ForwardingRuleApiLiveTest extends BaseGoogleComputeEngineApiLiveTes
    private static final String TARGETPOOL_NAME_NEW = "forwarding-rule-api-live-test-new-targetpool";
    private static final String DESCRIPTION = "Forwarding rule api live test forwarding rule.";
    private static final String ADDRESS_NAME = "forwarding-rule-api-address";
-   private static final int TIME_WAIT = 30;
    private TargetPool targetPool;
    private TargetPool newTargetPool;
    private Address address;
@@ -62,21 +61,21 @@ public class ForwardingRuleApiLiveTest extends BaseGoogleComputeEngineApiLiveTes
    @BeforeClass
    public void init() {
       TargetPoolCreationOptions targetPoolCreationOptions = new TargetPoolCreationOptions();
-      assertRegionOperationDoneSucessfully(targetPoolApi().create(TARGETPOOL_NAME, targetPoolCreationOptions), TIME_WAIT);
+      assertOperationDoneSuccessfully(targetPoolApi().create(TARGETPOOL_NAME, targetPoolCreationOptions));
       targetPool = targetPoolApi().get(TARGETPOOL_NAME);
 
-      assertRegionOperationDoneSucessfully(targetPoolApi().create(TARGETPOOL_NAME_NEW, targetPoolCreationOptions), TIME_WAIT);
+      assertOperationDoneSuccessfully(targetPoolApi().create(TARGETPOOL_NAME_NEW, targetPoolCreationOptions));
       newTargetPool = targetPoolApi().get(TARGETPOOL_NAME_NEW);
 
-      assertRegionOperationDoneSucessfully(addressApi().create(ADDRESS_NAME), TIME_WAIT);
+      assertOperationDoneSuccessfully(addressApi().create(ADDRESS_NAME));
       address = addressApi().get(ADDRESS_NAME);
    }
 
    @AfterClass
    public void tearDown() {
-      assertRegionOperationDoneSucessfully(targetPoolApi().delete(TARGETPOOL_NAME), TIME_WAIT);
-      assertRegionOperationDoneSucessfully(targetPoolApi().delete(TARGETPOOL_NAME_NEW), TIME_WAIT);
-      assertRegionOperationDoneSucessfully(addressApi().delete(ADDRESS_NAME), TIME_WAIT);
+      assertOperationDoneSuccessfully(targetPoolApi().delete(TARGETPOOL_NAME));
+      assertOperationDoneSuccessfully(targetPoolApi().delete(TARGETPOOL_NAME_NEW));
+      assertOperationDoneSuccessfully(addressApi().delete(ADDRESS_NAME));
    }
 
    @Test(groups = "live")
@@ -86,7 +85,7 @@ public class ForwardingRuleApiLiveTest extends BaseGoogleComputeEngineApiLiveTes
                                                                            .ipAddress(address.address())
                                                                            .ipProtocol(ForwardingRule.IPProtocol.TCP)
                                                                            .target(targetPool.selfLink());
-      assertRegionOperationDoneSucessfully(api().create(FORWARDING_RULE_NAME, forwardingRuleCreationOptions), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().create(FORWARDING_RULE_NAME, forwardingRuleCreationOptions));
    }
 
    @Test(groups = "live", dependsOnMethods = "testInsertForwardingRule")
@@ -102,7 +101,7 @@ public class ForwardingRuleApiLiveTest extends BaseGoogleComputeEngineApiLiveTes
 
    @Test(groups = "live", dependsOnMethods = "testGetForwardingRule")
    public void testSetTargetForwardingRule(){
-      assertRegionOperationDoneSucessfully(api().setTarget(FORWARDING_RULE_NAME, newTargetPool.selfLink()), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().setTarget(FORWARDING_RULE_NAME, newTargetPool.selfLink()));
       ForwardingRule forwardingRule = api().get(FORWARDING_RULE_NAME);
       assertNotNull(forwardingRule);
       assertEquals(forwardingRule.name(), FORWARDING_RULE_NAME);
@@ -117,6 +116,6 @@ public class ForwardingRuleApiLiveTest extends BaseGoogleComputeEngineApiLiveTes
 
    @Test(groups = "live", dependsOnMethods = {"testListForwardingRule", "testSetTargetForwardingRule"}, alwaysRun = true)
    public void testDeleteForwardingRule() {
-      assertRegionOperationDoneSucessfully(api().delete(FORWARDING_RULE_NAME), TIME_WAIT);
+      assertOperationDoneSuccessfully(api().delete(FORWARDING_RULE_NAME));
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs-google/blob/8895953d/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/GlobalOperationApiExpectTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/GlobalOperationApiExpectTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/GlobalOperationApiExpectTest.java
deleted file mode 100644
index 8209741..0000000
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/GlobalOperationApiExpectTest.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
-import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
-import static org.jclouds.googlecomputeengine.options.ListOptions.Builder.filter;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-
-import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
-import org.jclouds.googlecomputeengine.parse.ParseGlobalOperationListTest;
-import org.jclouds.googlecomputeengine.parse.ParseGlobalOperationTest;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpResponse;
-import org.testng.annotations.Test;
-
-@Test(groups = "unit", testName = "GlobalOperationApiExpectTest")
-public class GlobalOperationApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
-
-   private static final String OPERATIONS_URL_PREFIX = BASE_URL + "/myproject/global/operations";
-
-   public static final HttpRequest GET_GLOBAL_OPERATION_REQUEST = HttpRequest
-           .builder()
-           .method("GET")
-           .endpoint(OPERATIONS_URL_PREFIX + "/operation-1354084865060-4cf88735faeb8-bbbb12cb")
-           .addHeader("Accept", "application/json")
-           .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-   public static final HttpResponse GET_GLOBAL_OPERATION_RESPONSE = HttpResponse.builder().statusCode(200)
-           .payload(staticPayloadFromResource("/global_operation.json")).build();
-
-   public void testGetOperationResponseIs2xx() throws Exception {
-
-      GlobalOperationApi operationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, GET_GLOBAL_OPERATION_REQUEST, GET_GLOBAL_OPERATION_RESPONSE).getGlobalOperationApi("myproject");
-
-      assertEquals(operationApi.get("operation-1354084865060-4cf88735faeb8-bbbb12cb"),
-              new ParseGlobalOperationTest().expected());
-   }
-
-   public void testGetOperationResponseIs4xx() throws Exception {
-
-      HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
-
-      GlobalOperationApi globalOperationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, GET_GLOBAL_OPERATION_REQUEST, operationResponse).getGlobalOperationApi("myproject");
-
-      assertNull(globalOperationApi.get("operation-1354084865060-4cf88735faeb8-bbbb12cb"));
-   }
-
-   public void testDeleteOperationResponseIs2xx() throws Exception {
-      HttpRequest delete = HttpRequest
-              .builder()
-              .method("DELETE")
-              .endpoint(OPERATIONS_URL_PREFIX + "/operation-1352178598164-4cdcc9d031510-4aa46279")
-              .addHeader("Accept", "application/json")
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpResponse operationResponse = HttpResponse.builder().statusCode(204).build();
-
-      GlobalOperationApi globalOperationApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
-              TOKEN_RESPONSE, delete, operationResponse).getGlobalOperationApi("myproject");
-
-      globalOperationApi.delete("operation-1352178598164-4cdcc9d031510-4aa46279");
-   }
-
-   public void testDeleteOperationResponseIs4xx() throws Exception {
-      HttpRequest delete = HttpRequest
-              .builder()
-              .method("DELETE")
-              .endpoint(OPERATIONS_URL_PREFIX + "/operation-1352178598164-4cdcc9d031510-4aa46279")
-              .addHeader("Accept", "application/json")
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
-
-      GlobalOperationApi globalOperationApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
-              TOKEN_RESPONSE, delete, operationResponse).getGlobalOperationApi("myproject");
-
-      globalOperationApi.delete("operation-1352178598164-4cdcc9d031510-4aa46279");
-   }
-
-   public void testLisOperationWithNoOptionsResponseIs2xx() {
-      HttpRequest get = HttpRequest
-              .builder()
-              .method("GET")
-              .endpoint(OPERATIONS_URL_PREFIX)
-              .addHeader("Accept", "application/json")
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
-              .payload(payloadFromResource("/global_operation_list.json")).build();
-
-      GlobalOperationApi globalOperationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, get, operationResponse).getGlobalOperationApi("myproject");
-
-      assertEquals(globalOperationApi.list().next().toString(),
-              new ParseGlobalOperationListTest().expected().toString());
-   }
-
-   public void testListOperationWithPaginationOptionsResponseIs2xx() {
-      HttpRequest get = HttpRequest
-              .builder()
-              .method("GET")
-              .endpoint(OPERATIONS_URL_PREFIX +
-                      "?pageToken=CglPUEVSQVRJT04SOzU5MDQyMTQ4Nzg1Mi5vcG" +
-                      "VyYXRpb24tMTM1MjI0NDI1ODAzMC00Y2RkYmU2YTJkNmIwLWVkMzIyMzQz&" +
-                      "filter=" +
-                      "status%20eq%20done&" +
-                      "maxResults=3")
-              .addHeader("Accept", "application/json")
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
-              .payload(payloadFromResource("/global_operation_list.json")).build();
-
-      GlobalOperationApi globalOperationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, get, operationResponse).getGlobalOperationApi("myproject");
-
-      assertEquals(globalOperationApi.listPage("CglPUEVSQVRJT04SOzU5MDQyMTQ4Nzg1Mi5vcGVyYXRpb24tMTM1Mj" +
-              "I0NDI1ODAzMC00Y2RkYmU2YTJkNmIwLWVkMzIyMzQz",
-              filter("status eq done").maxResults(3)).toString(),
-              new ParseGlobalOperationListTest().expected().toString());
-   }
-
-   public void testListOperationWithPaginationOptionsResponseIs4xx() {
-      HttpRequest get = HttpRequest
-              .builder()
-              .method("GET")
-              .endpoint(OPERATIONS_URL_PREFIX)
-              .addHeader("Accept", "application/json")
-              .addHeader("Authorization", "Bearer " + TOKEN).build();
-
-      HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
-
-      GlobalOperationApi globalOperationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
-              TOKEN_RESPONSE, get, operationResponse).getGlobalOperationApi("myproject");
-
-      assertFalse(globalOperationApi.list().hasNext());
-   }
-}