You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2013/09/06 19:39:57 UTC

[08/11] JCLOUDS-209. Move to GCE v1beta15 API, with new features/methods included

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/DiskApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/DiskApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/DiskApi.java
index faa05d1..b771c74 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/DiskApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/DiskApi.java
@@ -19,8 +19,6 @@ package org.jclouds.googlecomputeengine.features;
 import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
 import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
 
-import java.net.URI;
-
 import javax.inject.Named;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -57,7 +55,7 @@ import org.jclouds.rest.binders.BindToJsonPayload;
  * Provides access to Disks via their REST API.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/disks"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/disks"/>
  */
 @SkipEncoding({'/', '='})
 @RequestFilters(OAuthAuthenticator.class)
@@ -66,25 +64,25 @@ public interface DiskApi {
    /**
     * Returns the specified persistent disk resource.
     *
+    * @param zone     Name of the zone the disk is in.
     * @param diskName name of the persistent disk resource to return.
     * @return a Disk resource.
     */
    @Named("Disks:get")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/disks/{disk}")
+   @Path("/zones/{zone}/disks/{disk}")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    @Nullable
-   Disk get(@PathParam("disk") String diskName);
+   Disk getInZone(@PathParam("zone") String zone, @PathParam("disk") String diskName);
 
    /**
     * Creates a persistent disk resource in the specified project specifying the size of the disk.
     *
-    *
     * @param diskName the name of disk.
     * @param sizeGb   the size of the disk
-    * @param zone     the URi of the zone where the disk is to be created.
+    * @param zone     the name of the zone where the disk is to be created.
     * @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.
     */
@@ -92,16 +90,17 @@ public interface DiskApi {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
-   @Path("/disks")
+   @Path("/zones/{zone}/disks")
    @OAuthScopes({COMPUTE_SCOPE})
    @MapBinder(BindToJsonPayload.class)
    Operation createInZone(@PayloadParam("name") String diskName,
-                                            @PayloadParam("sizeGb") int sizeGb,
-                                            @PayloadParam("zone") URI zone);
+                          @PayloadParam("sizeGb") int sizeGb,
+                          @PathParam("zone") String zone);
 
    /**
     * Deletes the specified persistent disk resource.
     *
+    * @param zone     the zone the disk is in.
     * @param diskName name of the persistent disk resource to delete.
     * @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
     *         you, and look for the status field.
@@ -109,41 +108,42 @@ public interface DiskApi {
    @Named("Disks:delete")
    @DELETE
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/disks/{disk}")
+   @Path("/zones/{zone}/disks/{disk}")
    @OAuthScopes(COMPUTE_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    @Nullable
-   Operation delete(@PathParam("disk") String diskName);
+   Operation deleteInZone(@PathParam("zone") String zone, @PathParam("disk") String diskName);
 
    /**
-    * @see DiskApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see DiskApi#listAtMarkerInZone(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("Disks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/disks")
+   @Path("/zones/{zone}/disks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseDisks.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Disk> listFirstPage();
+   ListPage<Disk> listFirstPageInZone(@PathParam("zone") String zone);
 
    /**
-    * @see DiskApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see DiskApi#listAtMarkerInZone(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("Disks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/disks")
+   @Path("/zones/{zone}/disks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseDisks.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Disk> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
+   ListPage<Disk> listAtMarkerInZone(@PathParam("zone") String zone, @QueryParam("pageToken") @Nullable String marker);
 
    /**
-    * Retrieves the listPage of persistent disk resources contained within the specified project.
+    * Retrieves the listPage of persistent disk resources contained within the specified project and zone.
     * By default the listPage as a maximum size of 100, if no options are provided or ListOptions#getMaxResults() has
     * not been set.
     *
+    * @param zone        the zone to search in
     * @param marker      marks the beginning of the next list page
     * @param listOptions listing options
     * @return a page of the listPage
@@ -153,36 +153,60 @@ public interface DiskApi {
    @Named("Disks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/disks")
+   @Path("/zones/{zone}/disks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseDisks.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Disk> listAtMarker(@QueryParam("pageToken") @Nullable String marker, ListOptions options);
+   ListPage<Disk> listAtMarkerInZone(@PathParam("zone") String zone, @QueryParam("pageToken") @Nullable String marker, ListOptions listOptions);
 
    /**
-    * A paged version of DiskApi#listPage()
+    * A paged version of DiskApi#listPageInZone(String)
     *
+    * @param zone the zone to list in
     * @return a Paged, Fluent Iterable that is able to fetch additional pages when required
     * @see PagedIterable
-    * @see DiskApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see DiskApi#listAtMarkerInZone(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("Disks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/disks")
+   @Path("/zones/{zone}/disks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseDisks.class)
    @Transform(ParseDisks.ToPagedIterable.class)
    @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
-   PagedIterable<Disk> list();
+   PagedIterable<Disk> listInZone(@PathParam("zone") String zone);
 
    @Named("Disks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/disks")
+   @Path("/zones/{zone}/disks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseDisks.class)
    @Transform(ParseDisks.ToPagedIterable.class)
    @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
-   PagedIterable<Disk> list(ListOptions options);
+   PagedIterable<Disk> listInZone(@PathParam("zone") String zone, ListOptions options);
+
+   /**
+    * Create a snapshot of a given disk in a zone.
+    *
+    * @param zone the zone the disk is in.
+    * @param diskName the name of the disk.
+    * @param snapshotName the name for the snapshot to be craeted.
+    *
+    * @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("Disks:createSnapshot")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/zones/{zone}/disks/{disk}/createSnapshot")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   @Nullable
+   Operation createSnapshotInZone(@PathParam("zone") String zone,
+                                  @PathParam("disk") String diskName,
+                                  @PayloadParam("name") String snapshotName);
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/FirewallApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/FirewallApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/FirewallApi.java
index 5a7a875..0c25b5b 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/FirewallApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/FirewallApi.java
@@ -63,7 +63,7 @@ import org.jclouds.rest.binders.BindToJsonPayload;
  * <p/>
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/firewalls"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/firewalls"/>
  */
 @SkipEncoding({'/', '='})
 @RequestFilters(OAuthAuthenticator.class)
@@ -77,7 +77,7 @@ public interface FirewallApi {
    @Named("Firewalls:get")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/firewalls/{firewall}")
+   @Path("/global/firewalls/{firewall}")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    @Nullable
@@ -86,8 +86,8 @@ public interface FirewallApi {
    /**
     * Creates a firewall resource in the specified project using the data included in the request.
     *
-    * @param name the name of the firewall to be inserted.
-    * @param network the network to which to add the firewall
+    * @param name            the name of the firewall to be inserted.
+    * @param network         the network to which to add the firewall
     * @param firewallOptions the options of the firewall to add
     * @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.
@@ -96,7 +96,7 @@ public interface FirewallApi {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
-   @Path("/firewalls")
+   @Path("/global/firewalls")
    @OAuthScopes({COMPUTE_SCOPE})
    @MapBinder(FirewallBinder.class)
    Operation createInNetwork(@PayloadParam("name") String name,
@@ -106,8 +106,8 @@ public interface FirewallApi {
    /**
     * Updates the specified firewall resource with the data included in the request.
     *
-    * @param firewallName the name firewall to be updated.
-    * @param firewallOptions     the new firewall.
+    * @param firewallName    the name firewall to be updated.
+    * @param firewallOptions the new firewall.
     * @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.
     */
@@ -115,7 +115,7 @@ public interface FirewallApi {
    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
-   @Path("/firewalls/{firewall}")
+   @Path("/global/firewalls/{firewall}")
    @OAuthScopes({COMPUTE_SCOPE})
    Operation update(@PathParam("firewall") String firewallName,
                     @BinderParam(BindToJsonPayload.class) FirewallOptions firewallOptions);
@@ -123,8 +123,8 @@ public interface FirewallApi {
    /**
     * Updates the specified firewall resource, with patch semantics, with the data included in the request.
     *
-    * @param firewallName the name firewall to be updated.
-    * @param firewallOptions     the new firewall.
+    * @param firewallName    the name firewall to be updated.
+    * @param firewallOptions the new firewall.
     * @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.
     */
@@ -132,7 +132,7 @@ public interface FirewallApi {
    @PATCH
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
-   @Path("/firewalls/{firewall}")
+   @Path("/global/firewalls/{firewall}")
    @OAuthScopes({COMPUTE_SCOPE})
    Operation patch(@PathParam("firewall") String firewallName,
                    @BinderParam(BindToJsonPayload.class) FirewallOptions firewallOptions);
@@ -140,14 +140,14 @@ public interface FirewallApi {
    /**
     * Deletes the specified image resource.
     *
-    * @param imageName name of the firewall resource to delete.
+    * @param firewallName name of the firewall resource to delete.
     * @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
     *         you, and look for the status field.  If the image did not exist the result is null.
     */
    @Named("Firewalls:delete")
    @DELETE
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/firewalls/{firewall}")
+   @Path("/global/firewalls/{firewall}")
    @OAuthScopes(COMPUTE_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    Operation delete(@PathParam("firewall") String firewallName);
@@ -158,7 +158,7 @@ public interface FirewallApi {
    @Named("Firewalls:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/firewalls")
+   @Path("/global/firewalls")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseFirewalls.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
@@ -170,7 +170,7 @@ public interface FirewallApi {
    @Named("Firewalls:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/firewalls")
+   @Path("/global/firewalls")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseFirewalls.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
@@ -190,7 +190,7 @@ public interface FirewallApi {
    @Named("Firewalls:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/firewalls")
+   @Path("/global/firewalls")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseFirewalls.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
@@ -202,7 +202,7 @@ public interface FirewallApi {
    @Named("Firewalls:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/firewalls")
+   @Path("/global/firewalls")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseFirewalls.class)
    @Transform(ParseFirewalls.ToPagedIterable.class)
@@ -219,7 +219,7 @@ public interface FirewallApi {
    @Named("Firewalls:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/firewalls")
+   @Path("/global/firewalls")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseFirewalls.class)
    @Transform(ParseFirewalls.ToPagedIterable.class)

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/GlobalOperationApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/GlobalOperationApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/GlobalOperationApi.java
new file mode 100644
index 0000000..0b1b4d1
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/GlobalOperationApi.java
@@ -0,0 +1,159 @@
+/*
+ * 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 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 javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
+import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.collect.PagedIterable;
+import org.jclouds.googlecomputeengine.domain.ListPage;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.functions.internal.ParseGlobalOperations;
+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.OAuthAuthenticator;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.SkipEncoding;
+import org.jclouds.rest.annotations.Transform;
+
+/**
+ * Provides access to Global Operations via their REST API.
+ *
+ * @author David Alves
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/globalOperations"/>
+ */
+@SkipEncoding({'/', '='})
+@RequestFilters(OAuthAuthenticator.class)
+public interface GlobalOperationApi {
+
+   /**
+    * Retrieves the specified operation resource.
+    *
+    * @param operationName name of the operation resource to return.
+    * @return If successful, this method returns an Operation resource
+    */
+   @Named("GlobalOperations:get")
+   @GET
+   @Path("/global/operations/{operation}")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   Operation get(@PathParam("operation") String operationName);
+
+   /**
+    * Deletes the specified operation resource.
+    *
+    * @param operationName name of the operation resource to delete.
+    */
+   @Named("GlobalOperations:delete")
+   @DELETE
+   @Path("/global/operations/{operation}")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   void delete(@PathParam("operation") String operationName);
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.GlobalOperationApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("GlobalOperations:list")
+   @GET
+   @Path("/global/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseGlobalOperations.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Operation> listFirstPage();
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.GlobalOperationApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("GlobalOperations:list")
+   @GET
+   @Path("/global/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseGlobalOperations.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Operation> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
+
+   /**
+    * Retrieves the listFirstPage of operation resources contained within the specified project.
+    * By default the listFirstPage as a maximum size of 100, if no options are provided or ListOptions#getMaxResults()
+    * has not been set.
+    *
+    * @param marker      marks the beginning of the next list page
+    * @param listOptions listing options
+    * @return a page of the list, starting at marker
+    * @see org.jclouds.googlecomputeengine.options.ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("GlobalOperations:list")
+   @GET
+   @Path("/global/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseGlobalOperations.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Operation> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
+                                    ListOptions listOptions);
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.GlobalOperationApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("GlobalOperations:list")
+   @GET
+   @Path("/global/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseGlobalOperations.class)
+   @Transform(ParseGlobalOperations.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<Operation> list();
+
+   /**
+    * A paged version of GlobalOperationApi#listFirstPage()
+    *
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages when required
+    * @see org.jclouds.collect.PagedIterable
+    * @see org.jclouds.googlecomputeengine.features.GlobalOperationApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("GlobalOperations:list")
+   @GET
+   @Path("/global/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseGlobalOperations.class)
+   @Transform(ParseGlobalOperations.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<Operation> list(ListOptions listOptions);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
index 74faa02..d3475e8 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ImageApi.java
@@ -51,7 +51,7 @@ import org.jclouds.rest.annotations.Transform;
  * <p/>
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/images"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/images"/>
  */
 @SkipEncoding({'/', '='})
 @RequestFilters(OAuthAuthenticator.class)
@@ -65,7 +65,7 @@ public interface ImageApi {
    @Named("Images:get")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/images/{image}")
+   @Path("/global/images/{image}")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    @Nullable
@@ -81,7 +81,7 @@ public interface ImageApi {
    @Named("Images:delete")
    @DELETE
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/images/{image}")
+   @Path("/global/images/{image}")
    @OAuthScopes(COMPUTE_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    @Nullable
@@ -93,7 +93,7 @@ public interface ImageApi {
    @Named("Images:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/images")
+   @Path("/global/images")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseImages.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
@@ -105,7 +105,7 @@ public interface ImageApi {
    @Named("Images:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/images")
+   @Path("/global/images")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseImages.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
@@ -116,7 +116,6 @@ public interface ImageApi {
     * By default the list as a maximum size of 100, if no options are provided or ListOptions#getMaxResults() has not
     * been set.
     *
-    *
     * @param marker      marks the beginning of the next list page
     * @param listOptions listing options
     * @return a page of the list
@@ -126,11 +125,11 @@ public interface ImageApi {
    @Named("Images:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/images")
+   @Path("/global/images")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseImages.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Image> listAtMarker(@QueryParam("pageToken") @Nullable String marker, ListOptions options);
+   ListPage<Image> listAtMarker(@QueryParam("pageToken") @Nullable String marker, ListOptions listOptions);
 
    /**
     * A paged version of ImageApi#list()
@@ -142,7 +141,7 @@ public interface ImageApi {
    @Named("Images:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/images")
+   @Path("/global/images")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseImages.class)
    @Transform(ParseImages.ToPagedIterable.class)
@@ -159,10 +158,11 @@ public interface ImageApi {
    @Named("Images:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/images")
+   @Path("/global/images")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseImages.class)
    @Transform(ParseImages.ToPagedIterable.class)
    @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
    PagedIterable<Image> list(ListOptions options);
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java
index c78d3da..7d123a6 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/InstanceApi.java
@@ -19,6 +19,9 @@ package org.jclouds.googlecomputeengine.features;
 import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
 import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
 
+import java.util.Map;
+import java.util.Set;
+
 import javax.inject.Named;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -40,6 +43,8 @@ import org.jclouds.googlecomputeengine.domain.ListPage;
 import org.jclouds.googlecomputeengine.domain.Operation;
 import org.jclouds.googlecomputeengine.functions.internal.ParseInstances;
 import org.jclouds.googlecomputeengine.handlers.InstanceBinder;
+import org.jclouds.googlecomputeengine.handlers.MetadataBinder;
+import org.jclouds.googlecomputeengine.options.AttachDiskOptions;
 import org.jclouds.googlecomputeengine.options.ListOptions;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.oauth.v2.config.OAuthScopes;
@@ -58,7 +63,7 @@ import org.jclouds.rest.binders.BindToJsonPayload;
  * Provides access to Instances via their REST API.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/instances"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/instances"/>
  * @see InstanceApi
  */
 @SkipEncoding({'/', '='})
@@ -68,24 +73,26 @@ public interface InstanceApi {
    /**
     * Returns the specified instance resource.
     *
+    * @param zone zone the instance is in.
     * @param instanceName name of the instance resource to return.
     * @return an Instance resource
     */
    @Named("Instances:get")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/instances/{instance}")
+   @Path("/zones/{zone}/instances/{instance}")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    @Nullable
-   Instance get(@PathParam("instance") String instanceName);
+   Instance getInZone(@PathParam("zone") String zone, @PathParam("instance") String instanceName);
 
    /**
     * Creates a instance resource in the specified project using the data included in the request.
     *
+    *
     * @param instanceName this name of the instance to be created
-    * @param template the instance template
     * @param zone the name of the zone where the instance will be created
+    * @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.
     */
@@ -93,16 +100,17 @@ public interface InstanceApi {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
-   @Path("/instances")
+   @Path("/zones/{zone}/instances")
    @OAuthScopes({COMPUTE_SCOPE})
    @MapBinder(InstanceBinder.class)
-   Operation createInZone(@PayloadParam("name") String instanceName,
-                          @PayloadParam("template") InstanceTemplate template,
-                          @PayloadParam("zone") String zone);
+   Operation createInZone(@PayloadParam("name") String instanceName, @PathParam("zone") String zone,
+                          @PayloadParam("template") InstanceTemplate template);
+                          
 
    /**
     * Deletes the specified instance resource.
     *
+    * @param zone the instance is in.
     * @param instanceName name of the instance resource to delete.
     * @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
     *         you, and look for the status field.  If the instance did not exist the result is null.
@@ -110,33 +118,35 @@ public interface InstanceApi {
    @Named("Instances:delete")
    @DELETE
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/instances/{instance}")
+   @Path("/zones/{zone}/instances/{instance}")
    @OAuthScopes(COMPUTE_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    @Nullable
-   Operation delete(@PathParam("instance") String instanceName);
+   Operation deleteInZone(@PathParam("zone") String zone, @PathParam("instance") String instanceName);
 
    /**
-    * A paged version of InstanceApi#list()
+    * A paged version of InstanceApi#listInZone()
     *
+    * @param zone zone instances are in
     * @return a Paged, Fluent Iterable that is able to fetch additional pages when required
     * @see PagedIterable
-    * @see InstanceApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see InstanceApi#listAtMarkerInZone(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("Instances:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/instances")
+   @Path("/zones/{zone}/instances")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseInstances.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Instance> listFirstPage();
+   ListPage<Instance> listFirstPageInZone(@PathParam("zone") String zone);
 
    /**
     * Retrieves the list of instance 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 zone zone instances are in
     * @param marker      marks the beginning of the next list page
     * @param listOptions listing options
     * @return a page of the list
@@ -146,53 +156,56 @@ public interface InstanceApi {
    @Named("Instances:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/instances")
+   @Path("/zones/{zone}/instances")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseInstances.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Instance> listAtMarker(@Nullable String marker);
+   ListPage<Instance> listAtMarkerInZone(@PathParam("zone") String zone, @Nullable String marker,
+                                         ListOptions listOptions);
 
    /**
-    * @see InstanceApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see InstanceApi#listAtMarkerInZone(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("Instances:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/instances")
+   @Path("/zones/{zone}/instances")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseInstances.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Instance> listAtMarker(@Nullable String marker, ListOptions options);
+   ListPage<Instance> listAtMarkerInZone(@PathParam("zone") String zone,
+                                         @Nullable String marker);
 
    /**
-    * @see InstanceApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see InstanceApi#listInZone(String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("Instances:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/instances")
+   @Path("/zones/{zone}/instances")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseInstances.class)
    @Transform(ParseInstances.ToPagedIterable.class)
    @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
-   PagedIterable<Instance> list();
+   PagedIterable<Instance> listInZone(@PathParam("zone") String zone);
 
    /**
-    * @see InstanceApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see InstanceApi#listInZone(String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("Instances:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/instances")
+   @Path("/zones/{zone}/instances")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseInstances.class)
    @Transform(ParseInstances.ToPagedIterable.class)
    @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
-   PagedIterable<Instance> list(ListOptions options);
+   PagedIterable<Instance> listInZone(@PathParam("zone") String zone, ListOptions options);
 
    /**
     * Adds an access config to an instance's network interface.
     *
+    * @param zone zone instance is in
     * @param instanceName         the instance name.
     * @param accessConfig         the AccessConfig to add.
     * @param networkInterfaceName network interface name.
@@ -203,16 +216,18 @@ public interface InstanceApi {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
-   @Path("/instances/{instance}/addAccessConfig")
+   @Path("/zones/{zone}/instances/{instance}/addAccessConfig")
    @OAuthScopes({COMPUTE_SCOPE})
-   Operation addAccessConfigToNic(@PathParam("instance") String instanceName,
-                                  @BinderParam(BindToJsonPayload.class)
-                                  Instance.NetworkInterface.AccessConfig accessConfig,
-                                  @QueryParam("network_interface") String networkInterfaceName);
-
+   Operation addAccessConfigToNicInZone(@PathParam("zone") String zone,
+                                        @PathParam("instance") String instanceName,
+                                        @BinderParam(BindToJsonPayload.class)
+                                        Instance.NetworkInterface.AccessConfig accessConfig,
+                                        @QueryParam("network_interface") String networkInterfaceName);
+  
    /**
     * Deletes an access config from an instance's network interface.
     *
+    * @param zone zone instance is in
     * @param instanceName         the instance name.
     * @param accessConfigName     the name of the access config to delete
     * @param networkInterfaceName network interface name.
@@ -222,22 +237,146 @@ public interface InstanceApi {
    @Named("Instances:deleteAccessConfig")
    @DELETE
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/instances/{instance}/deleteAccessConfig")
+   @Path("/zones/{zone}/instances/{instance}/deleteAccessConfig")
    @OAuthScopes(COMPUTE_SCOPE)
-   Operation deleteAccessConfigFromNic(@PathParam("instance") String instanceName,
-                                       @QueryParam("access_config") String accessConfigName,
-                                       @QueryParam("network_interface") String networkInterfaceName);
+   Operation deleteAccessConfigFromNicInZone(@PathParam("zone") String zone,
+                                             @PathParam("instance") String instanceName,
+                                             @QueryParam("access_config") String accessConfigName,
+                                             @QueryParam("network_interface") String networkInterfaceName);
 
    /**
     * Returns the specified instance's serial port output.
     *
+    * @param zone zone instance is in
     * @param instanceName the instance name.
     * @return if successful, this method returns a SerialPortOutput containing the instance's serial output.
     */
    @Named("Instances:serialPort")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/instances/{instance}/serialPort")
+   @Path("/zones/{zone}/instances/{instance}/serialPort")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   Instance.SerialPortOutput getSerialPortOutput(@PathParam("instance") String instanceName);
+   Instance.SerialPortOutput getSerialPortOutputInZone(@PathParam("zone") String zone,
+                                                       @PathParam("instance") String instanceName);
+
+   /**
+    * Hard-resets the instance.
+    *
+    * @param zone         the zone the instance is in
+    * @param instanceName the instance name
+    * @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
+    *         you, and look for the status field.  If the instance did not exist the result is null.
+    */
+   @Named("Instances:reset")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/zones/{zone}/instances/{instance}/reset")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Operation resetInZone(@PathParam("zone") String zone,
+                         @PathParam("instance") String instanceName);
+
+   /**
+    * Attaches a disk to an instance
+    *
+    * @param zone The zone the instance is in.
+    * @param instanceName The instance name to attach to
+    * @param attachDiskOptions The options for attaching the disk.
+    *
+    * @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
+    *         you, and look for the status field.
+    */
+   @Named("Instances:attachDisk")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Path("/zones/{zone}/instances/{instance}/attachDisk")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Operation attachDiskInZone(@PathParam("zone") String zone,
+                              @PathParam("instance") String instanceName,
+                              @BinderParam(BindToJsonPayload.class) AttachDiskOptions attachDiskOptions);
+
+   /**
+    * Detaches an attached disk from an instance
+    *
+    * @param zone The zone the instance is in.
+    * @param instanceName The instance name to attach to
+    * @param deviceName The device name of the disk to detach.
+    *
+    * @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("Instances:detachDisk")
+   @POST
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Path("/zones/{zone}/instances/{instance}/detachDisk")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Operation detachDiskInZone(@PathParam("zone") String zone,
+                              @PathParam("instance") String instanceName,
+                              @QueryParam("deviceName") String deviceName);
+
+   /**
+    * Sets metadata for an instance using the data included in the request.
+    * <p/>
+    * NOTE: This *sets* metadata items on the project (vs *adding* items to metadata),
+    * if there are pre-existing metadata items that must be kept these must be fetched first and then re-set on the
+    * new Metadata, e.g.
+    * <pre><tt>
+    *    Metadata.Builder current = instanceApi.getInZone("us-central1-a", "myInstance").getMetadata().toBuilder();
+    *    current.addItem("newItem","newItemValue");
+    *    instanceApi.setMetadataInZone("us-central1-a", "myInstance", current.build());
+    * </tt></pre>
+    *
+    * @param zone The zone the instance is in
+    * @param instanceName The name of the instance
+    * @param metadata the metadata to set
+    * @param fingerprint The current fingerprint for the items
+    *
+    * @return an Operations resource. To check on the status of an operation, poll the Operations resource returned
+    *         to you, and look for the status field.
+    */
+   @Named("Instances:setMetadata")
+   @POST
+   @Path("/zones/{zone}/instances/{instance}/setMetadata")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   @MapBinder(MetadataBinder.class)
+   @Nullable
+   Operation setMetadataInZone(@PathParam("zone") String zone,
+                               @PathParam("instance") String instanceName,
+                               @PayloadParam("items") Map<String, String> metadata,
+                               @PayloadParam("fingerprint") String fingerprint);
+
+   /**
+    * Sets items for an instance
+    *
+    * @param zone The zone the instance is in
+    * @param instanceName the name of the instance
+    * @param items A set of items
+    * @param fingerprint The current fingerprint for the items
+    * @return an Operations resource. To check on the status of an operation, poll the Operations resource returned
+    *         to you, and look for the status field.
+    */
+   @Named("Instances:setTags")
+   @POST
+   @Path("/zones/{zone}/instances/{instance}/setTags")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Produces(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   @MapBinder(BindToJsonPayload.class)
+   @Nullable
+   Operation setTagsInZone(@PathParam("zone") String zone,
+                           @PathParam("instance") String instanceName,
+                           @PayloadParam("items") Set<String> items,
+                           @PayloadParam("fingerprint") String fingerprint);
+
 }
+

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/KernelApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/KernelApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/KernelApi.java
index a707bb5..76acf9c 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/KernelApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/KernelApi.java
@@ -47,7 +47,7 @@ import org.jclouds.rest.annotations.Transform;
  * Provides access to Kernels via their REST API.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/kernels"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/kernels"/>
  */
 @SkipEncoding({'/', '='})
 @RequestFilters(OAuthAuthenticator.class)
@@ -62,7 +62,7 @@ public interface KernelApi {
     */
    @Named("Kernels:get")
    @GET
-   @Path("/kernels/{kernel}")
+   @Path("/global/kernels/{kernel}")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    Kernel get(@PathParam("kernel") String kernelName);
@@ -72,7 +72,7 @@ public interface KernelApi {
     */
    @Named("Kernels:list")
    @GET
-   @Path("/kernels")
+   @Path("/global/kernels")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseKernels.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
@@ -83,7 +83,7 @@ public interface KernelApi {
     */
    @Named("Kernels:list")
    @GET
-   @Path("/kernels")
+   @Path("/global/kernels")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseKernels.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
@@ -102,19 +102,19 @@ public interface KernelApi {
     */
    @Named("Kernels:list")
    @GET
-   @Path("/kernels")
+   @Path("/global/kernels")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseKernels.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
    ListPage<Kernel> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
-                                                   ListOptions listOptions);
+                                 ListOptions listOptions);
 
    /**
     * @see KernelApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("Kernels:list")
    @GET
-   @Path("/kernels")
+   @Path("/global/kernels")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseKernels.class)
    @Transform(ParseKernels.ToPagedIterable.class)
@@ -130,7 +130,7 @@ public interface KernelApi {
     */
    @Named("Kernels:list")
    @GET
-   @Path("/kernels")
+   @Path("/global/kernels")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseKernels.class)
    @Transform(ParseKernels.ToPagedIterable.class)

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/MachineTypeApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/MachineTypeApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/MachineTypeApi.java
index a27e2e4..acdd24f 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/MachineTypeApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/MachineTypeApi.java
@@ -47,7 +47,7 @@ import org.jclouds.rest.annotations.Transform;
  * Provides access to MachineTypes via their REST API.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/machineTypes"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/machineTypes"/>
  */
 @SkipEncoding({'/', '='})
 @RequestFilters(OAuthAuthenticator.class)
@@ -57,44 +57,45 @@ public interface MachineTypeApi {
    /**
     * Returns the specified machine type resource
     *
+    * @param zone            the name of the zone the machine type is in
     * @param machineTypeName name of the machine type resource to return.
     * @return If successful, this method returns a MachineType resource
     */
    @Named("MachineTypes:get")
    @GET
-   @Path("/machineTypes/{machineType}")
+   @Path("/zones/{zone}/machineTypes/{machineType}")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
-   MachineType get(@PathParam("machineType") String machineTypeName);
+   MachineType getInZone(@PathParam("zone") String zone, @PathParam("machineType") String machineTypeName);
 
    /**
-    * @see MachineTypeApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see MachineTypeApi#listAtMarkerInZone(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("MachineTypes:list")
    @GET
-   @Path("/machineTypes")
+   @Path("/zones/{zone}/machineTypes")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseMachineTypes.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<MachineType> listFirstPage();
+   ListPage<MachineType> listFirstPageInZone(@PathParam("zone") String zone);
 
    /**
-    * @see MachineTypeApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see MachineTypeApi#listAtMarkerInZone(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("MachineTypes:list")
    @GET
-   @Path("/machineTypes")
+   @Path("/zones/{zone}/machineTypes")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseMachineTypes.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<MachineType> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
+   ListPage<MachineType> listAtMarkerInZone(@PathParam("zone") String zone, @QueryParam("pageToken") @Nullable String marker);
 
    /**
     * Retrieves the list of machine type 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 zone        The name of the zone to list in.
     * @param marker      marks the beginning of the next list page
     * @param listOptions listing options
     * @return a page of the list
@@ -103,39 +104,41 @@ public interface MachineTypeApi {
     */
    @Named("MachineTypes:list")
    @GET
-   @Path("/machineTypes")
+   @Path("/zones/{zone}/machineTypes")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseMachineTypes.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<MachineType> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
-                                                        ListOptions listOptions);
+   ListPage<MachineType> listAtMarkerInZone(@PathParam("zone") String zone,
+                                            @QueryParam("pageToken") @Nullable String marker,
+                                            ListOptions listOptions);
 
    /**
-    * @see MachineTypeApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see MachineTypeApi#listInZone(String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("MachineTypes:list")
    @GET
-   @Path("/machineTypes")
+   @Path("/zones/{zone}/machineTypes")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseMachineTypes.class)
    @Transform(ParseMachineTypes.ToPagedIterable.class)
    @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
-   PagedIterable<MachineType> list();
+   PagedIterable<MachineType> listInZone(@PathParam("zone") String zone);
 
    /**
-    * A paged version of MachineTypeApi#list()
+    * A paged version of MachineTypeApi#listInZone(String)
     *
+    * @param zone the zone to list in
     * @return a Paged, Fluent Iterable that is able to fetch additional pages when required
     * @see PagedIterable
-    * @see MachineTypeApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see MachineTypeApi#listAtMarkerInZone(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
     */
    @Named("MachineTypes:list")
    @GET
-   @Path("/machineTypes")
+   @Path("/zones/{zone}/machineTypes")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseMachineTypes.class)
    @Transform(ParseMachineTypes.ToPagedIterable.class)
    @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
-   PagedIterable<MachineType> list(ListOptions listOptions);
+   PagedIterable<MachineType> listInZone(@PathParam("zone") String zone, ListOptions listOptions);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/NetworkApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/NetworkApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/NetworkApi.java
index ca15787..5a04ccd 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/NetworkApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/NetworkApi.java
@@ -55,7 +55,7 @@ import org.jclouds.rest.binders.BindToJsonPayload;
  * Provides access to Networks via their REST API.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/networks"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/networks"/>
  */
 @SkipEncoding({'/', '='})
 @RequestFilters(OAuthAuthenticator.class)
@@ -70,7 +70,7 @@ public interface NetworkApi {
    @Named("Networks:get")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/networks/{network}")
+   @Path("/global/networks/{network}")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    Network get(@PathParam("network") String networkName);
@@ -87,11 +87,11 @@ public interface NetworkApi {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
-   @Path("/networks")
+   @Path("/global/networks")
    @OAuthScopes({COMPUTE_SCOPE})
    @MapBinder(BindToJsonPayload.class)
    Operation createInIPv4Range(@PayloadParam("name") String networkName,
-                                                 @PayloadParam("IPv4Range") String IPv4Range);
+                               @PayloadParam("IPv4Range") String IPv4Range);
 
    /**
     * Creates a persistent network resource in the specified project with the specified range and specified gateway.
@@ -106,12 +106,12 @@ public interface NetworkApi {
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
-   @Path("/networks")
+   @Path("/global/networks")
    @OAuthScopes({COMPUTE_SCOPE})
    @MapBinder(BindToJsonPayload.class)
    Operation createInIPv4RangeWithGateway(@PayloadParam("name") String networkName,
-                                                            @PayloadParam("IPv4Range") String IPv4Range,
-                                                            @PayloadParam("gatewayIPv4") String gatewayIPv4);
+                                          @PayloadParam("IPv4Range") String IPv4Range,
+                                          @PayloadParam("gatewayIPv4") String gatewayIPv4);
 
    /**
     * Deletes the specified persistent network resource.
@@ -123,7 +123,7 @@ public interface NetworkApi {
    @Named("Networks:delete")
    @DELETE
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/networks/{network}")
+   @Path("/global/networks/{network}")
    @OAuthScopes(COMPUTE_SCOPE)
    @Fallback(NullOnNotFoundOr404.class)
    Operation delete(@PathParam("network") String networkName);
@@ -134,7 +134,7 @@ public interface NetworkApi {
    @Named("Networks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/networks")
+   @Path("/global/networks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseNetworks.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
@@ -146,7 +146,7 @@ public interface NetworkApi {
    @Named("Networks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/networks")
+   @Path("/global/networks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseNetworks.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
@@ -157,7 +157,6 @@ public interface NetworkApi {
     * By default the list as a maximum size of 100, if no options are provided or ListOptions#getMaxResults() has not
     * been set.
     *
-    *
     * @param marker      marks the beginning of the next list page
     * @param listOptions listing options
     * @return a page of the list
@@ -167,12 +166,12 @@ public interface NetworkApi {
    @Named("Networks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/networks")
+   @Path("/global/networks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseNetworks.class)
    @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
    ListPage<Network> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
-                                                    ListOptions options);
+                                  ListOptions options);
 
    /**
     * @see NetworkApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
@@ -180,7 +179,7 @@ public interface NetworkApi {
    @Named("Networks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/networks")
+   @Path("/global/networks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseNetworks.class)
    @Transform(ParseNetworks.ToPagedIterable.class)
@@ -197,7 +196,7 @@ public interface NetworkApi {
    @Named("Networks:list")
    @GET
    @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/networks")
+   @Path("/global/networks")
    @OAuthScopes(COMPUTE_READONLY_SCOPE)
    @ResponseParser(ParseNetworks.class)
    @Transform(ParseNetworks.ToPagedIterable.class)

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/OperationApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/OperationApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/OperationApi.java
deleted file mode 100644
index fc8da71..0000000
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/OperationApi.java
+++ /dev/null
@@ -1,159 +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 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 javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
-import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.collect.PagedIterable;
-import org.jclouds.googlecomputeengine.domain.ListPage;
-import org.jclouds.googlecomputeengine.domain.Operation;
-import org.jclouds.googlecomputeengine.functions.internal.ParseOperations;
-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.OAuthAuthenticator;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.ResponseParser;
-import org.jclouds.rest.annotations.SkipEncoding;
-import org.jclouds.rest.annotations.Transform;
-
-/**
- * Provides access to Operations via their REST API.
- *
- * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/operations"/>
- */
-@SkipEncoding({'/', '='})
-@RequestFilters(OAuthAuthenticator.class)
-public interface OperationApi {
-
-   /**
-    * Retrieves the specified operation resource.
-    *
-    * @param operationName name of the operation resource to return.
-    * @return If successful, this method returns an Operation resource
-    */
-   @Named("Operations:get")
-   @GET
-   @Path("/operations/{operation}")
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(NullOnNotFoundOr404.class)
-   Operation get(@PathParam("operation") String operationName);
-
-   /**
-    * Deletes the specified operation resource.
-    *
-    * @param operationName name of the operation resource to delete.
-    */
-   @Named("Operations:delete")
-   @DELETE
-   @Path("/operations/{operation}")
-   @OAuthScopes(COMPUTE_SCOPE)
-   @Fallback(NullOnNotFoundOr404.class)
-   void delete(@PathParam("operation") String operationName);
-
-   /**
-    * @see OperationApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
-    */
-   @Named("Operations:list")
-   @GET
-   @Path("/operations")
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @ResponseParser(ParseOperations.class)
-   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Operation> listFirstPage();
-
-   /**
-    * @see OperationApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
-    */
-   @Named("Operations:list")
-   @GET
-   @Path("/operations")
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @ResponseParser(ParseOperations.class)
-   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Operation> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
-
-   /**
-    * Retrieves the listFirstPage of operation resources contained within the specified project.
-    * By default the listFirstPage as a maximum size of 100, if no options are provided or ListOptions#getMaxResults()
-    * has not been set.
-    *
-    * @param marker      marks the beginning of the next list page
-    * @param listOptions listing options
-    * @return a page of the list, starting at marker
-    * @see ListOptions
-    * @see org.jclouds.googlecomputeengine.domain.ListPage
-    */
-   @Named("Operations:list")
-   @GET
-   @Path("/operations")
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @ResponseParser(ParseOperations.class)
-   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
-   ListPage<Operation> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
-                                                      ListOptions listOptions);
-
-   /**
-    * @see OperationApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
-    */
-   @Named("Operations:list")
-   @GET
-   @Path("/operations")
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @ResponseParser(ParseOperations.class)
-   @Transform(ParseOperations.ToPagedIterable.class)
-   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
-   PagedIterable<Operation> list();
-
-   /**
-    * A paged version of OperationApi#listFirstPage()
-    *
-    * @return a Paged, Fluent Iterable that is able to fetch additional pages when required
-    * @see PagedIterable
-    * @see OperationApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
-    */
-   @Named("Operations:list")
-   @GET
-   @Path("/operations")
-   @OAuthScopes(COMPUTE_READONLY_SCOPE)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @ResponseParser(ParseOperations.class)
-   @Transform(ParseOperations.ToPagedIterable.class)
-   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
-   PagedIterable<Operation> list(ListOptions listOptions);
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ProjectApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ProjectApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ProjectApi.java
index d33d22d..acabab3 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ProjectApi.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/ProjectApi.java
@@ -36,8 +36,9 @@ import org.jclouds.googlecomputeengine.domain.Project;
 import org.jclouds.googlecomputeengine.handlers.MetadataBinder;
 import org.jclouds.oauth.v2.config.OAuthScopes;
 import org.jclouds.oauth.v2.filters.OAuthAuthenticator;
-import org.jclouds.rest.annotations.BinderParam;
 import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.PayloadParam;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.SkipEncoding;
 
@@ -45,7 +46,7 @@ import org.jclouds.rest.annotations.SkipEncoding;
  * Provides access to Projects via their REST API.
  *
  * @author David Alves
- * @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/projects"/>
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/projects"/>
  */
 @SkipEncoding({'/', '='})
 @RequestFilters(OAuthAuthenticator.class)
@@ -78,7 +79,8 @@ public interface ProjectApi {
     * </tt></pre>
     *
     * @param projectName            name of the project to return
-    * @param commonInstanceMetadata the metadata to set
+    * @param metadata the metadata to set
+    * @param fingerprint  The current fingerprint for the metadata
     * @return an Operations resource. To check on the status of an operation, poll the Operations resource returned
     *         to you, and look for the status field.
     */
@@ -88,7 +90,8 @@ public interface ProjectApi {
    @OAuthScopes(COMPUTE_SCOPE)
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(MetadataBinder.class)
    Operation setCommonInstanceMetadata(@PathParam("project") String projectName,
-                                                         @BinderParam(MetadataBinder.class)
-                                                         Map<String, String> commonInstanceMetadata);
+                                       @PayloadParam("items") Map<String, String> metadata,
+                                       @PayloadParam("fingerprint") String fingerprint);
 }

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RegionApi.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RegionApi.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RegionApi.java
new file mode 100644
index 0000000..dcc81ad
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RegionApi.java
@@ -0,0 +1,136 @@
+/*
+ * 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 javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
+import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.collect.PagedIterable;
+import org.jclouds.googlecomputeengine.domain.ListPage;
+import org.jclouds.googlecomputeengine.domain.Region;
+import org.jclouds.googlecomputeengine.functions.internal.ParseRegions;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.oauth.v2.config.OAuthScopes;
+import org.jclouds.oauth.v2.filters.OAuthAuthenticator;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.SkipEncoding;
+import org.jclouds.rest.annotations.Transform;
+
+/**
+ * Provides access to Regions via their REST API.
+ *
+ * @author David Alves
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/regions"/>
+ */
+@SkipEncoding({'/', '='})
+@RequestFilters(OAuthAuthenticator.class)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface RegionApi {
+
+   /**
+    * Returns the specified region resource
+    *
+    * @param regionName name of the region resource to return.
+    * @return If successful, this method returns a Region resource
+    */
+   @Named("Regions:get")
+   @GET
+   @Path("/regions/{region}")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   Region get(@PathParam("region") String regionName);
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.RegionApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("Regions:list")
+   @GET
+   @Path("/regions")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseRegions.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Region> listFirstPage();
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.RegionApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("Regions:list")
+   @GET
+   @Path("/regions")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseRegions.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Region> listAtMarker(String marker);
+
+   /**
+    * Retrieves the listFirstPage of region resources available to the specified project.
+    * By default the listFirstPage as a maximum size of 100, if no options are provided or ListOptions#getMaxResults()
+    * has not been set.
+    *
+    * @param marker      marks the beginning of the next list page
+    * @param listOptions listing options
+    * @return a page of the listFirstPage
+    * @see org.jclouds.googlecomputeengine.options.ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("Regions:list")
+   @GET
+   @Path("/regions")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseRegions.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Region> listAtMarker(String marker, ListOptions listOptions);
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.RegionApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("Regions:list")
+   @GET
+   @Path("/regions")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseRegions.class)
+   @Transform(ParseRegions.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<Region> list();
+
+   /**
+    * A paged version of RegionApi#listFirstPage()
+    *
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages when required
+    * @see org.jclouds.googlecomputeengine.features.RegionApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    * @see org.jclouds.collect.PagedIterable
+    */
+   @Named("Regions:list")
+   @GET
+   @Path("/regions")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @ResponseParser(ParseRegions.class)
+   @Transform(ParseRegions.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<Region> list(ListOptions listOptions);
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/53386380/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
new file mode 100644
index 0000000..0707f79
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/features/RegionOperationApi.java
@@ -0,0 +1,164 @@
+/*
+ * 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 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 javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
+import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.collect.PagedIterable;
+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.OAuthAuthenticator;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.SkipEncoding;
+import org.jclouds.rest.annotations.Transform;
+
+/**
+ * Provides access to Operations via their REST API.
+ *
+ * @author David Alves
+ * @see <a href="https://developers.google.com/compute/docs/reference/v1beta15/operations"/>
+ */
+@SkipEncoding({'/', '='})
+@RequestFilters(OAuthAuthenticator.class)
+public interface RegionOperationApi {
+
+   /**
+    * Retrieves the specified operation resource.
+    *
+    * @param region        the region the operation is in
+    * @param operationName name of the operation resource to return.
+    * @return If successful, this method returns an Operation resource
+    */
+   @Named("RegionOperations:get")
+   @GET
+   @Path("/regions/{region}/operations/{operation}")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   Operation getInRegion(@PathParam("region") String region, @PathParam("operation") String operationName);
+
+   /**
+    * Deletes the specified operation resource.
+    *
+    * @param region        the region the operation is in
+    * @param operationName name of the operation resource to delete.
+    */
+   @Named("RegionOperations:delete")
+   @DELETE
+   @Path("/regions/{region}/operations/{operation}")
+   @OAuthScopes(COMPUTE_SCOPE)
+   @Fallback(NullOnNotFoundOr404.class)
+   void deleteInRegion(@PathParam("region") String region, @PathParam("operation") String operationName);
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.RegionOperationApi#listAtMarkerInRegion(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("RegionOperations:list")
+   @GET
+   @Path("/regions/{region}/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseRegionOperations.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Operation> listFirstPageInRegion(@PathParam("region") String region);
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.RegionOperationApi#listAtMarkerInRegion(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("RegionOperations:list")
+   @GET
+   @Path("/regions/{region}/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseRegionOperations.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Operation> listAtMarkerInRegion(@PathParam("region") String region,
+                                            @QueryParam("pageToken") @Nullable String marker);
+
+   /**
+    * Retrieves the listFirstPage of operation resources contained within the specified project.
+    * By default the listFirstPage as a maximum size of 100, if no options are provided or ListOptions#getMaxResults()
+    * has not been set.
+    *
+    * @param region      the region to list in
+    * @param marker      marks the beginning of the next list page
+    * @param listOptions listing options
+    * @return a page of the list, starting at marker
+    * @see org.jclouds.googlecomputeengine.options.ListOptions
+    * @see org.jclouds.googlecomputeengine.domain.ListPage
+    */
+   @Named("RegionOperations:list")
+   @GET
+   @Path("/regions/{region}/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseRegionOperations.class)
+   @Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
+   ListPage<Operation> listAtMarkerInRegion(@PathParam("region") String region,
+                                            @QueryParam("pageToken") @Nullable String marker,
+                                            ListOptions listOptions);
+
+   /**
+    * @see org.jclouds.googlecomputeengine.features.RegionOperationApi#listInRegion(String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("RegionOperations:list")
+   @GET
+   @Path("/regions/{region}/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseRegionOperations.class)
+   @Transform(ParseRegionOperations.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<Operation> listInRegion(@PathParam("region") String region);
+
+   /**
+    * A paged version of RegionOperationApi#listFirstPageInRegion(String)
+    *
+    * @return a Paged, Fluent Iterable that is able to fetch additional pages when required
+    * @see org.jclouds.collect.PagedIterable
+    * @see org.jclouds.googlecomputeengine.features.RegionOperationApi#listAtMarkerInRegion(String, String, org.jclouds.googlecomputeengine.options.ListOptions)
+    */
+   @Named("RegionOperations:list")
+   @GET
+   @Path("/regions/{region}/operations")
+   @OAuthScopes(COMPUTE_READONLY_SCOPE)
+   @Consumes(MediaType.APPLICATION_JSON)
+   @ResponseParser(ParseRegionOperations.class)
+   @Transform(ParseRegionOperations.ToPagedIterable.class)
+   @Fallback(EmptyPagedIterableOnNotFoundOr404.class)
+   PagedIterable<Operation> listInRegion(@PathParam("region") String region, ListOptions listOptions);
+
+}