You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by jd...@apache.org on 2014/07/15 23:29:31 UTC

[4/5] JCLOUDS-40: Unasync OpenStack Nova API

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAdministrationAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAdministrationAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAdministrationAsyncApi.java
deleted file mode 100644
index db32512..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAdministrationAsyncApi.java
+++ /dev/null
@@ -1,156 +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.openstack.nova.v2_0.extensions;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.nova.v2_0.domain.Host;
-import org.jclouds.openstack.nova.v2_0.domain.HostResourceUsage;
-import org.jclouds.openstack.nova.v2_0.functions.FieldValueResponseParsers.MaintenanceModeDisabledResponseParser;
-import org.jclouds.openstack.nova.v2_0.functions.FieldValueResponseParsers.MaintenanceModeEnabledResponseParser;
-import org.jclouds.openstack.nova.v2_0.functions.FieldValueResponseParsers.PowerIsRebootResponseParser;
-import org.jclouds.openstack.nova.v2_0.functions.FieldValueResponseParsers.PowerIsShutdownResponseParser;
-import org.jclouds.openstack.nova.v2_0.functions.FieldValueResponseParsers.PowerIsStartupResponseParser;
-import org.jclouds.openstack.nova.v2_0.functions.FieldValueResponseParsers.StatusDisabledResponseParser;
-import org.jclouds.openstack.nova.v2_0.functions.FieldValueResponseParsers.StatusEnabledResponseParser;
-import org.jclouds.openstack.v2_0.ServiceType;
-import org.jclouds.openstack.v2_0.services.Extension;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.Payload;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.ResponseParser;
-import org.jclouds.rest.annotations.SelectJson;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.FluentIterable;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to Host Administration features via the REST API.
- * <p/>
- *
- * @see HostAdministrationApi
- * @see <a href= "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"/>
- * @see <a href="http://nova.openstack.org/api_ext" />
- * @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.hosts.html" />
- */
-@Beta
-@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.HOSTS)
-@RequestFilters(AuthenticateRequest.class)
-@Path("/os-hosts")
-@Consumes(MediaType.APPLICATION_JSON)
-public interface HostAdministrationAsyncApi {
-
-   /**
-    * @see HostAdministrationApi#list()
-    */
-   @Named("hostadmin:list")
-   @GET
-   @SelectJson("hosts")
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<? extends FluentIterable<? extends Host>> list();
-
-   /**
-    * @see HostAdministrationApi#listResourceUsage(String)
-    */
-   @Named("hostadmin:listresource")
-   @GET
-   @Path("/{id}")
-   @SelectJson("host")
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<? extends FluentIterable<? extends HostResourceUsage>> listResourceUsage(@PathParam("id") String hostId);
-
-   /**
-    * @see HostAdministrationApi#enable(String)
-    */
-   @Named("hostadmin:enable")
-   @PUT
-   @Produces(MediaType.APPLICATION_JSON)
-   @Path("/{id}")
-   @Payload("{\"status\":\"enable\"}")
-   @ResponseParser(StatusEnabledResponseParser.class)
-   ListenableFuture<Boolean> enable(@PathParam("id") String hostId);
-
-   /**
-    * @see HostAdministrationApi#disable(String) 
-    */
-   @Named("hostadmin:disable")
-   @PUT
-   @Produces(MediaType.APPLICATION_JSON)
-   @Path("/{id}")
-   @Payload("{\"status\":\"disable\"}")
-   @ResponseParser(StatusDisabledResponseParser.class)
-   ListenableFuture<Boolean> disable(@PathParam("id") String hostId);
-
-   /**
-    * @see HostAdministrationApi#startMaintenance(String)
-    */
-   @Named("hostadmin:startmaintenance")
-   @PUT
-   @Produces(MediaType.APPLICATION_JSON)
-   @Path("/{id}")
-   @Payload("{\"maintenance_mode\":\"enable\"}")
-   @ResponseParser(MaintenanceModeEnabledResponseParser.class)
-   ListenableFuture<Boolean> startMaintenance(@PathParam("id") String hostId);
-
-   /**
-    * @see HostAdministrationApi#stopMaintenance(String)
-    */
-   @Named("hostadmin:stopmaintenance")
-   @PUT
-   @Produces(MediaType.APPLICATION_JSON)
-   @Path("/{id}")
-   @Payload("{\"maintenance_mode\":\"disable\"}")
-   @ResponseParser(MaintenanceModeDisabledResponseParser.class)
-   ListenableFuture<Boolean> stopMaintenance(@PathParam("id") String hostId);
-
-   /**
-    * @see HostAdministrationApi#startup(String)
-    */
-   @Named("hostadmin:startup")
-   @GET
-   @Path("/{id}/startup")
-   @ResponseParser(PowerIsStartupResponseParser.class)
-   ListenableFuture<Boolean> startup(@PathParam("id") String hostId);
-
-   /**
-    * @see HostAdministrationApi#shutdown(String)
-    */
-   @Named("hostadmin:shutdown")
-   @GET
-   @Path("/{id}/shutdown")
-   @ResponseParser(PowerIsShutdownResponseParser.class)
-   ListenableFuture<Boolean> shutdown(@PathParam("id") String hostId);
-
-   /**
-    * @see HostAdministrationApi#reboot(String)
-    */
-   @Named("hostadmin:reboot")
-   @GET
-   @Path("/{id}/reboot")
-   @ResponseParser(PowerIsRebootResponseParser.class)
-   ListenableFuture<Boolean> reboot(@PathParam("id") String hostId);
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAggregateApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAggregateApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAggregateApi.java
index 5e36d03..b291ca0 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAggregateApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAggregateApi.java
@@ -17,70 +17,141 @@
 package org.jclouds.openstack.nova.v2_0.extensions;
 
 import java.util.Map;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.HostAggregate;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+import org.jclouds.rest.annotations.WrapWith;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.FluentIterable;
 
 /**
- * Provide access to Host Aggregates in Nova (alias "OS-AGGREGATES")
- *
- * @see HostAggregateAsyncApi
- * @see <a href="http://nova.openstack.org/api_ext/ext_aggregates.html"/>
- * @see <a href="http://wiki.openstack.org/host-aggregates"/>
+ * Provide access to the OpenStack Compute (Nova) Host Aggregates extension API.
  */
 @Beta
 @Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.AGGREGATES)
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/os-aggregates")
 public interface HostAggregateApi {
-
    /**
+    * Lists all host aggregates.
+    *
     * @return the set of host aggregates.
     */
-   FluentIterable<? extends HostAggregate> list();
+   @Named("hostAggregate:list")
+   @GET
+   @SelectJson("aggregates")
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<HostAggregate> list();
 
    /**
     * Retrieves the details of an aggregate, hosts and metadata included.
     *
     * @return the details of the aggregate requested.
     */
-   HostAggregate get(String id);
+   @Named("hostAggregate:get")
+   @GET
+   @Path("/{id}")
+   @SelectJson("aggregate")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   HostAggregate get(@PathParam("id") String id);
 
    /**
     * Creates an aggregate, given its name and availability zone.
-    * 
+    *
     * @return the newly created Aggregate
     */
-   HostAggregate createInAvailabilityZone(String name, String availabilityZone);
+   @Named("hostAggregate:create")
+   @POST
+   @SelectJson("aggregate")
+   @Produces(MediaType.APPLICATION_JSON)
+   @WrapWith("aggregate")
+   HostAggregate createInAvailabilityZone(@PayloadParam("name") String name,
+         @PayloadParam("availability_zone") String availabilityZone);
 
    /**
     * Updates the name of an aggregate.
     */
-   HostAggregate updateName(String id, String name);
+   @Named("hostAggregate:update")
+   @POST
+   @Path("/{id}")
+   @SelectJson("aggregate")
+   @WrapWith("aggregate")
+   HostAggregate updateName(@PathParam("id") String id, @PayloadParam("name") String name);
 
    /**
-    * Updates the availability zone an aggregate.
+    * Updates the availability zone for an aggregate.
     */
-   HostAggregate updateAvailabilityZone(String id, String availabilityZone);
+   @Named("hostAggregate:update")
+   @POST
+   @Path("/{id}")
+   @SelectJson("aggregate")
+   @WrapWith("aggregate")
+   HostAggregate updateAvailabilityZone(@PathParam("id") String id,
+         @PayloadParam("availability_zone") String availabilityZone);
 
    /**
     * Removes an aggregate.
     */
-   Boolean delete(String id);
+   @Named("hostAggregate:delete")
+   @DELETE
+   @Path("/{id}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean delete(@PathParam("id") String id);
 
    /**
     * Adds a host to an aggregate
     */
-   HostAggregate addHost(String id, String host);
+   @Named("hostAggregate:addHost")
+   @POST
+   @Path("/{id}/action")
+   @SelectJson("aggregate")
+   @Produces(MediaType.APPLICATION_JSON)
+   @WrapWith("add_host")
+   HostAggregate addHost(@PathParam("id") String id, @PayloadParam("host") String host);
 
    /**
     * Removes a host from an aggregate
     */
-   HostAggregate removeHost(String id, String host);
+   @Named("hostAggregate:removeHost")
+   @POST
+   @Path("/{id}/action")
+   @SelectJson("aggregate")
+   @Produces(MediaType.APPLICATION_JSON)
+   @WrapWith("remove_host")
+   HostAggregate removeHost(@PathParam("id") String id, @PayloadParam("host") String host);
 
    /**
     * Adds metadata to an aggregate
     */
-   HostAggregate setMetadata(String id, Map<String, String> metadata);
+   @Named("hostAggregate:setMetadata")
+   @POST
+   @Path("/{id}/action")
+   @SelectJson("aggregate")
+   @Produces(MediaType.APPLICATION_JSON)
+   @WrapWith("set_metadata")
+   HostAggregate setMetadata(@PathParam("id") String id,
+         @PayloadParam("metadata") Map<String, String> metadata);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAggregateAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAggregateAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAggregateAsyncApi.java
deleted file mode 100644
index 1af58bd..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAggregateAsyncApi.java
+++ /dev/null
@@ -1,160 +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.openstack.nova.v2_0.extensions;
-
-import java.util.Map;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.nova.v2_0.domain.HostAggregate;
-import org.jclouds.openstack.v2_0.ServiceType;
-import org.jclouds.openstack.v2_0.services.Extension;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.PayloadParam;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-import org.jclouds.rest.annotations.WrapWith;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.FluentIterable;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provide access to Aggregates in Nova.
- *
- * @see HostAggregateApi
- */
-@Beta
-@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.AGGREGATES)
-@RequestFilters(AuthenticateRequest.class)
-@Path("/os-aggregates")
-public interface HostAggregateAsyncApi {
-
-   /**
-    * @see HostAggregateApi#list()
-    */
-   @Named("hostaggregate:list")
-   @GET
-   @SelectJson("aggregates")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<? extends FluentIterable<? extends HostAggregate>> list();
-
-   /**
-    * @see HostAggregateApi#get(String)
-    */
-   @Named("hostaggregate:get")
-   @GET
-   @Path("/{id}")
-   @SelectJson("aggregate")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<? extends HostAggregate> get(@PathParam("id") String id);
-
-   /**
-    * @see HostAggregateApi#createInAvailabilityZone(String, String)
-    */
-   @Named("hostaggregate:create")
-   @POST
-   @SelectJson("aggregate")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @WrapWith("aggregate")
-   ListenableFuture<? extends HostAggregate> createInAvailabilityZone(@PayloadParam("name") String name,
-                                                   @PayloadParam("availability_zone") String availabilityZone);
-
-   /**
-    * @see HostAggregateApi#updateName
-    */
-   @Named("hostaggregate:update")
-   @POST
-   @Path("/{id}")
-   @SelectJson("aggregate")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @WrapWith("aggregate")
-   ListenableFuture<? extends HostAggregate> updateName(@PathParam("id") String id, @PayloadParam("name") String name);
-
-   /**
-    * @see HostAggregateApi#updateAvailabilityZone
-    */
-   @Named("hostaggregate:update")
-   @POST
-   @Path("/{id}")
-   @SelectJson("aggregate")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @WrapWith("aggregate")
-   ListenableFuture<? extends HostAggregate> updateAvailabilityZone(@PathParam("id") String id, @PayloadParam("availability_zone") String availabilityZone);
-   
-   /**
-    * @see HostAggregateApi#delete(String)
-    */
-   @Named("hostaggregate:delete")
-   @DELETE
-   @Path("/{id}")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> delete(@PathParam("id") String id);
-
-   /**
-    * @see HostAggregateApi#addHost(String,String)
-    */
-   @Named("hostaggregate:addhost")
-   @POST
-   @Path("/{id}/action")
-   @SelectJson("aggregate")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @WrapWith("add_host")
-   ListenableFuture<? extends HostAggregate> addHost(@PathParam("id") String id, @PayloadParam("host") String host);
-
-
-   /**
-    * @see HostAggregateApi#removeHost(String,String)
-    */
-   @Named("hostaggregate:removehost")
-   @POST
-   @Path("/{id}/action")
-   @SelectJson("aggregate")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @WrapWith("remove_host")
-   ListenableFuture<? extends HostAggregate> removeHost(@PathParam("id") String id, @PayloadParam("host") String host);
-
-   /**
-    * @see HostAggregateApi#setMetadata
-    */
-   @Named("hostaggregate:setmetadata")
-   @POST
-   @Path("/{id}/action")
-   @SelectJson("aggregate")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @WrapWith("set_metadata")
-   ListenableFuture<? extends HostAggregate> setMetadata(@PathParam("id") String id, @PayloadParam("metadata") Map<String, String> metadata);
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/KeyPairApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/KeyPairApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/KeyPairApi.java
index 41818b5..cdc1d17 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/KeyPairApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/KeyPairApi.java
@@ -16,63 +16,111 @@
  */
 package org.jclouds.openstack.nova.v2_0.extensions;
 
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.nova.v2_0.binders.BindKeyPairToJsonPayload;
 import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
+import org.jclouds.openstack.nova.v2_0.functions.internal.ParseKeyPairs;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.Payload;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.SelectJson;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.FluentIterable;
 
 /**
- * Provides synchronous access to the OpenStack Nova Key Pair Extension API.
- * <p/>
- * 
- * @see KeyPairAsyncApi
+ * Provides access to the OpenStack Compute (Nova) Key Pair Extension API.
  */
 @Beta
 @Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.KEYPAIRS)
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/os-keypairs")
 public interface KeyPairApi {
-
    /**
     * Lists all Key Pairs.
-    * 
+    *
     * @return all Key Pairs
     */
+   @Named("keypair:list")
+   @GET
+   @ResponseParser(ParseKeyPairs.class)
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
    FluentIterable<KeyPair> list();
 
    /**
     * Creates a {@link KeyPair}.
-    * 
+    *
     * @return the created {@link KeyPair}.
     */
-   KeyPair create(String name);
+   @Named("keypair:create")
+   @POST
+   @SelectJson("keypair")
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("%7B\"keypair\":%7B\"name\":\"{name}\"%7D%7D")
+   KeyPair create(@PayloadParam("name") String name);
 
 
    /**
     * Creates a {@link KeyPair} with a public key.
-    * 
+    *
     * @return the created {@link KeyPair}.
     */
-   KeyPair createWithPublicKey(String name, String publicKey);
+   @Named("keypair:create")
+   @POST
+   @SelectJson("keypair")
+   @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(BindKeyPairToJsonPayload.class)
+   KeyPair createWithPublicKey(@PayloadParam("name") String name,
+         @PayloadParam("public_key") String publicKey);
 
    /**
     * Gets a specific {@link KeyPair} by name.
-    * 
+    *
     * @param name
     *           the name of the {@link KeyPair}
-    * 
+    *
     * @return the specified {@link KeyPair}, otherwise null.
     */
-   KeyPair get(String name);
+   @Named("keypair:get")
+   @GET
+   @Path("/{name}")
+   @SelectJson("keypair")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   KeyPair get(@PathParam("name") String name);
 
    /**
     * Deletes a {@link KeyPair}.
-    * 
+    *
     * @param name
     *           the name of the {@link KeyPair}
-    * 
+    *
     * @return {@code true} if the {@link KeyPair} was deleted, otherwise {@code false}.
     */
-   boolean delete(String name);
-
+   @Named("keypair:delete")
+   @DELETE
+   @Path("/{name}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean delete(@PathParam("name") String name);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/KeyPairAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/KeyPairAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/KeyPairAsyncApi.java
deleted file mode 100644
index 8e5c20a..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/KeyPairAsyncApi.java
+++ /dev/null
@@ -1,105 +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.openstack.nova.v2_0.extensions;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.nova.v2_0.binders.BindKeyPairToJsonPayload;
-import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
-import org.jclouds.openstack.nova.v2_0.functions.internal.ParseKeyPairs;
-import org.jclouds.openstack.v2_0.ServiceType;
-import org.jclouds.openstack.v2_0.services.Extension;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.MapBinder;
-import org.jclouds.rest.annotations.Payload;
-import org.jclouds.rest.annotations.PayloadParam;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.ResponseParser;
-import org.jclouds.rest.annotations.SelectJson;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.FluentIterable;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to the OpenStack Nova Key Pair Extension API.
- * <p/>
- * 
- * @see KeyPairApi
- */
-@Beta
-@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.KEYPAIRS)
-@RequestFilters(AuthenticateRequest.class)
-public interface KeyPairAsyncApi {
-
-   @Named("keypair:list")
-   @GET
-   @Path("/os-keypairs")
-   @ResponseParser(ParseKeyPairs.class)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<FluentIterable<KeyPair>> list();
-
-   @Named("keypair:create")
-   @POST
-   @Path("/os-keypairs")
-   @SelectJson("keypair")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("%7B\"keypair\":%7B\"name\":\"{name}\"%7D%7D")
-   ListenableFuture<KeyPair> create(@PayloadParam("name") String name);
-
-   @Named("keypair:get")
-   @GET
-   @Path("/os-keypairs/{name}")
-   @SelectJson("keypair")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(NullOnNotFoundOr404.class)
-   @Nullable
-   ListenableFuture<KeyPair> get(@PathParam("name") String name);
-
-   @Named("keypair:create")
-   @POST
-   @Path("/os-keypairs")
-   @SelectJson("keypair")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @MapBinder(BindKeyPairToJsonPayload.class)
-   ListenableFuture<KeyPair> createWithPublicKey(@PayloadParam("name") String name,
-         @PayloadParam("public_key") String publicKey);
-
-   @Named("keypair:delete")
-   @DELETE
-   @Path("/os-keypairs/{name}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   @Consumes
-   ListenableFuture<Boolean> delete(@PathParam("name") String name);
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/QuotaApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/QuotaApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/QuotaApi.java
index 9833fd0..ce7aeb8 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/QuotaApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/QuotaApi.java
@@ -16,41 +16,78 @@
  */
 package org.jclouds.openstack.nova.v2_0.extensions;
 
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.Quota;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
+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.SelectJson;
+import org.jclouds.rest.binders.BindToJsonPayload;
 
 import com.google.common.annotations.Beta;
 
 /**
+ * Provide access to OpenStack Compute (Nova) Quota Extension API.
+ * <p/>
  * The quotas extension enables limiters placed on the resources used per tenant (project) for virtual instances. It is
  * used with the OpenStack Compute API 1.1 for administrators who need to control the amount of volumes, memory, floating
  * IP addresses, instances, or cores allowed within a defined tenant or project.
  * <p/>
  * To use this extension, you need to have administrative rights to the tenants upon which you are placing quotas.
  *
- * @see QuotaAsyncApi
- * @see <a href="http://nova.openstack.org/api_ext/ext_quotas.html"/>
  */
 @Beta
 @Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.QUOTAS)
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/os-quota-sets")
 public interface QuotaApi {
-
    /**
     * @return the quota settings for the tenant
     */
-   Quota getByTenant(String tenantId);
+   @Named("quota:get")
+   @GET
+   @SelectJson("quota_set")
+   @Path("/{id}")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Quota getByTenant(@PathParam("id") String tenantId);
 
    /**
     * Update the quotas for a given tenant
     *
     * @return true if successful
     */
-   boolean updateQuotaOfTenant(Quota quota, String tenantId);
+   @Named("quota:update")
+   @PUT
+   @Path("/{id}")
+   @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(BindToJsonPayload.class)
+   boolean updateQuotaOfTenant(@PayloadParam("quota_set") Quota quota,
+         @PathParam("id") String tenantId);
 
    /**
     * @return the set of default quotas for the tenant
     */
-   Quota getDefaultsForTenant(String tenantId);
-
+   @Named("quota:get")
+   @GET
+   @SelectJson("quota_set")
+   @Path("/{id}/defaults")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Quota getDefaultsForTenant(@PathParam("id") String tenantId);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/QuotaAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/QuotaAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/QuotaAsyncApi.java
deleted file mode 100644
index 8c325f8..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/QuotaAsyncApi.java
+++ /dev/null
@@ -1,88 +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.openstack.nova.v2_0.extensions;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.nova.v2_0.domain.Quota;
-import org.jclouds.openstack.v2_0.ServiceType;
-import org.jclouds.openstack.v2_0.services.Extension;
-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.SelectJson;
-import org.jclouds.rest.binders.BindToJsonPayload;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provide access to Quota information for Nova tenants.
- * 
- * @see QuotaApi
- * @see <a href="http://nova.openstack.org/api_ext/ext_quotas.html"/>
- */
-@Beta
-@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.QUOTAS)
-@RequestFilters(AuthenticateRequest.class)
-@Path("/os-quota-sets")
-public interface QuotaAsyncApi {
-
-   /**
-    * @see QuotaApi#getDefaultsForTenant(String)
-    */
-   @Named("quota:get")
-   @GET
-   @SelectJson("quota_set")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/{tenant_id}")
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<? extends Quota> getByTenant(@PathParam("tenant_id") String tenantId);
-
-   /**
-    * @see QuotaApi#updateQuotaOfTenant
-    */
-   @Named("quota:update")
-   @PUT
-   @Path("/{tenant_id}")
-   @Produces(MediaType.APPLICATION_JSON)
-   @MapBinder(BindToJsonPayload.class)
-   ListenableFuture<Boolean> updateQuotaOfTenant(@PayloadParam("quota_set") Quota quota,
-            @PathParam("tenant_id") String tenantId);
-
-   /**
-    * @see QuotaApi#getDefaultsForTenant(String)
-    */
-   @Named("quota:get")
-   @GET
-   @SelectJson("quota_set")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/{tenant_id}/defaults")
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<? extends Quota> getDefaultsForTenant(@PathParam("tenant_id") String tenantId);
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java
index 77fa489..ec37d65 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupApi.java
@@ -16,73 +16,139 @@
  */
 package org.jclouds.openstack.nova.v2_0.extensions;
 
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.nova.v2_0.binders.BindSecurityGroupRuleToJsonPayload;
 import org.jclouds.openstack.nova.v2_0.domain.Ingress;
 import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
 import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.Payload;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.FluentIterable;
 
 /**
- * Provides synchronous access to Security Groups.
- * <p/>
- * 
- * @see SecurityGroupAsyncApi
+ * Provides access to the OpenStack Compute (Nova) Security Group extension API.
  */
 @Beta
 @Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SECURITY_GROUPS)
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(MediaType.APPLICATION_JSON)
 public interface SecurityGroupApi {
-
    /**
     * List all Security Groups.
-    * 
+    *
     * @return all Security Groups
     */
-   FluentIterable<? extends SecurityGroup> list();
+   @Named("securityGroup:list")
+   @GET
+   @Path("/os-security-groups")
+   @SelectJson("security_groups")
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<SecurityGroup> list();
 
    /**
     * Get a specific Security Group
-    * 
+    *
     * @return a specific Security Group
     */
-   SecurityGroup get(String id);
+   @Named("securityGroup:get")
+   @GET
+   @Path("/os-security-groups/{id}")
+   @SelectJson("security_group")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   SecurityGroup get(@PathParam("id") String id);
 
    /**
     * Create a Security Group
-    * 
+    *
     * @return a new Security Group
     */
-   SecurityGroup createWithDescription(String name, String description);
+   @Named("securityGroup:create")
+   @POST
+   @Path("/os-security-groups")
+   @SelectJson("security_group")
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("%7B\"security_group\":%7B\"name\":\"{name}\",\"description\":\"{description}\"%7D%7D")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   SecurityGroup createWithDescription(@PayloadParam("name") String name,
+         @PayloadParam("description") String description);
 
    /**
     * Delete a Security Group.
-    * 
+    *
     * @return
     */
-   boolean delete(String id);
+   @Named("securityGroup:delete")
+   @DELETE
+   @Path("/os-security-groups/{id}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean delete(@PathParam("id") String id);
 
    /**
     * Create a Security Group Rule.
-    * 
+    *
     * @return a new Security Group Rule
     */
-   SecurityGroupRule createRuleAllowingCidrBlock(String parentGroup, Ingress ingress, String sourceCidr);
+   @Named("securityGroup:create")
+   @POST
+   @Path("/os-security-group-rules")
+   @SelectJson("security_group_rule")
+   @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(BindSecurityGroupRuleToJsonPayload.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   SecurityGroupRule createRuleAllowingCidrBlock(
+         @PayloadParam("parent_group_id") String parentGroup, Ingress ip_protocol,
+         @PayloadParam("cidr") String sourceCidr);
 
    /**
     * Create a Security Group Rule.
-    * 
+    *
     * @return a new Security Group Rule
     */
-   SecurityGroupRule createRuleAllowingSecurityGroupId(String parentGroup, Ingress ingress,
-            String groupId);
+   @Named("securityGroup:create")
+   @POST
+   @Path("/os-security-group-rules")
+   @SelectJson("security_group_rule")
+   @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(BindSecurityGroupRuleToJsonPayload.class)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   SecurityGroupRule createRuleAllowingSecurityGroupId(
+         @PayloadParam("parent_group_id") String parentGroup, Ingress ip_protocol,
+         @PayloadParam("group_id") String groupId);
 
    /**
     * Delete a Security Group Rule.
-    * 
+    *
     * @return
     */
-   Boolean deleteRule(String id);
-
+   @Named("securityGroup:delete")
+   @DELETE
+   @Path("/os-security-group-rules/{id}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean deleteRule(@PathParam("id") String ruleId);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupAsyncApi.java
deleted file mode 100644
index ceb261c..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SecurityGroupAsyncApi.java
+++ /dev/null
@@ -1,151 +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.openstack.nova.v2_0.extensions;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.nova.v2_0.binders.BindSecurityGroupRuleToJsonPayload;
-import org.jclouds.openstack.nova.v2_0.domain.Ingress;
-import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
-import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
-import org.jclouds.openstack.v2_0.ServiceType;
-import org.jclouds.openstack.v2_0.services.Extension;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.MapBinder;
-import org.jclouds.rest.annotations.Payload;
-import org.jclouds.rest.annotations.PayloadParam;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.FluentIterable;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to Security Groups via the REST API.
- * <p/>
- * 
- * @see SecurityGroupApi
- * @see <a href= "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html"
- *      />
- * @see <a href="http://nova.openstack.org/api_ext" />
- * @see <a href="http://wiki.openstack.org/os-security-groups" />
- */
-@Beta
-@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SECURITY_GROUPS)
-@RequestFilters(AuthenticateRequest.class)
-public interface SecurityGroupAsyncApi {
-
-   /**
-    * @see SecurityGroupApi#list
-    */
-   @Named("securitygroup:list")
-   @GET
-   @SelectJson("security_groups")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/os-security-groups")
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<? extends FluentIterable<? extends SecurityGroup>> list();
-
-   /**
-    * @see SecurityGroupApi#get
-    */
-   @Named("securitygroup:get")
-   @GET
-   @Path("/os-security-groups/{id}")
-   @SelectJson("security_group")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<? extends SecurityGroup> get(@PathParam("id") String id);
-
-   /**
-    * @see SecurityGroupApi#createWithDescription
-    */
-   @Named("securitygroup:create")
-   @POST
-   @Path("/os-security-groups")
-   @SelectJson("security_group")
-   @Fallback(NullOnNotFoundOr404.class)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("%7B\"security_group\":%7B\"name\":\"{name}\",\"description\":\"{description}\"%7D%7D")
-   ListenableFuture<? extends SecurityGroup> createWithDescription(@PayloadParam("name") String name,
-            @PayloadParam("description") String description);
-
-   /**
-    * @see SecurityGroupApi#delete
-    */
-   @Named("securitygroup:delete")
-   @DELETE
-   @Path("/os-security-groups/{id}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   @Consumes(MediaType.APPLICATION_JSON)
-   ListenableFuture<Boolean> delete(@PathParam("id") String id);
-
-   /**
-    * @see SecurityGroupApi#createRuleAllowingCidrBlock
-    */
-   @Named("securitygroup:create")
-   @POST
-   @Path("/os-security-group-rules")
-   @SelectJson("security_group_rule")
-   @Fallback(NullOnNotFoundOr404.class)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @MapBinder(BindSecurityGroupRuleToJsonPayload.class)
-   ListenableFuture<? extends SecurityGroupRule> createRuleAllowingCidrBlock(
-            @PayloadParam("parent_group_id") String parent_group_id, Ingress ip_protocol,
-            @PayloadParam("cidr") String cidr);
-
-   /**
-    * @see SecurityGroupApi#createRuleOnSecurityGroupToCidrBlock
-    */
-   @Named("securitygroup:create")
-   @POST
-   @Path("/os-security-group-rules")
-   @SelectJson("security_group_rule")
-   @Fallback(NullOnNotFoundOr404.class)
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @MapBinder(BindSecurityGroupRuleToJsonPayload.class)
-   ListenableFuture<? extends SecurityGroupRule> createRuleAllowingSecurityGroupId(
-            @PayloadParam("parent_group_id") String parent_group_id, Ingress ip_protocol,
-            @PayloadParam("group_id") String group_id);
-
-   /**
-    * @see SecurityGroupApi#deleteRule
-    */
-   @Named("securitygroup:delete")
-   @DELETE
-   @Path("/os-security-group-rules/{security_group_rule_ID}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   @Consumes
-   ListenableFuture<Boolean> deleteRule(@PathParam("security_group_rule_ID") String security_group_rule_ID);
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerAdminApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerAdminApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerAdminApi.java
index a741955..bf22f40 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerAdminApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerAdminApi.java
@@ -16,65 +16,116 @@
  */
 package org.jclouds.openstack.nova.v2_0.extensions;
 
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.fallbacks.MapHttp4xxCodesToExceptions;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.BackupType;
+import org.jclouds.openstack.nova.v2_0.functions.ParseImageIdFromLocationHeader;
 import org.jclouds.openstack.nova.v2_0.options.CreateBackupOfServerOptions;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.Payload;
+import org.jclouds.rest.annotations.PayloadParam;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.ResponseParser;
+import org.jclouds.rest.annotations.WrapWith;
 
 import com.google.common.annotations.Beta;
 
 /**
+ * Provide access to the OpenStack Compute (Nova) Admin Server Actions Extension API.
+ *
  * Provide additional actions for servers:
  * 'suspend', 'resume', 'migrate', 'lock', 'unlock', 'resetNetwork', 'createBackup', 'pause', 'migrateLive',
  * 'injectNetworkInfo', 'unpause'
  *
- * @see org.jclouds.openstack.nova.v2_0.extensions.ServerAdminAsyncApi
  */
 @Beta
 @Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.ADMIN_ACTIONS)
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/servers/{id}/action")
 public interface ServerAdminApi {
-
    /**
     * Suspend a server.
     *
     * @param id id of the server
     */
-   Boolean suspend(String id);
+   @Named("serverAdmin:suspend")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("{\"suspend\":null}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean suspend(@PathParam("id") String id);
 
    /**
     * Resume a server.
     *
     * @param id id of the server
     */
-   Boolean resume(String id);
+   @Named("serverAdmin:resume")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("{\"resume\":null}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean resume(@PathParam("id") String id);
 
    /**
     * Migrate a server.
     *
     * @param id id of the server
     */
-   Boolean migrate(String id);
+   @Named("serverAdmin:migrate")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("{\"migrate\":null}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean migrate(@PathParam("id") String id);
 
    /**
     * Lock a server.
     *
     * @param id id of the server
     */
-   Boolean lock(String id);
+   @Named("serverAdmin:lock")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("{\"lock\":null}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean lock(@PathParam("id") String id);
 
    /**
     * Unlock a server.
     *
     * @param id id of the server
     */
-   Boolean unlock(String id);
+   @Named("serverAdmin:unlock")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("{\"unlock\":null}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean unlock(@PathParam("id") String id);
 
    /**
     * Reset network of a server.
     *
     * @param id id of the server
     */
-   Boolean resetNetwork(String id);
+   @Named("serverAdmin:resetNetwork")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("{\"resetNetwork\":null}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean resetNetwork(@PathParam("id") String id);
 
    /**
     * Create backup of a server.
@@ -86,34 +137,63 @@ public interface ServerAdminApi {
     * @param options    optional rotation and/or metadata parameters
     * @return the id of the newly created image
     */
-   String createBackup(String id, String imageName, BackupType backupType, int rotation, CreateBackupOfServerOptions... options);
+   @Named("serverAdmin:createBackup")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @WrapWith("createBackup")
+   @ResponseParser(ParseImageIdFromLocationHeader.class)
+   @Fallback(MapHttp4xxCodesToExceptions.class)
+   String createBackup(@PathParam("id") String id, @PayloadParam("name") String imageName,
+         @PayloadParam("backup_type") BackupType backupType, @PayloadParam("rotation") int rotation,
+         CreateBackupOfServerOptions... options);
 
    /**
     * Pause a server.
     *
     * @param id id of the server
     */
-   Boolean pause(String id);
+   @Named("serverAdmin:pause")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("{\"pause\":null}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean pause(@PathParam("id") String id);
 
    /**
     * Unpause a server.
     *
     * @param id id of the server
     */
-   Boolean unpause(String id);
-
+   @Named("serverAdmin:unpause")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("{\"unpause\":null}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean unpause(@PathParam("id") String id);
 
    /**
     * Live migrate a server.
     *
     * @param id id of the server
     */
-   Boolean liveMigrate(String id, String host, boolean blockMigration, boolean diskOverCommit);
+   @Named("serverAdmin:liveMigrate")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @WrapWith("os-migrateLive")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean liveMigrate(@PathParam("id") String id, @PayloadParam("host") String host,
+         @PayloadParam("block_migration") boolean blockMigration,
+         @PayloadParam("disk_over_commit") boolean diskOverCommit);
 
    /**
     * Inject network info into a server.
     *
     * @param id id of the server
     */
-   Boolean injectNetworkInfo(String id);
+   @Named("serverAdmin:injectNetwork")
+   @POST
+   @Produces(MediaType.APPLICATION_JSON)
+   @Payload("{\"injectNetworkInfo\":null}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean injectNetworkInfo(@PathParam("id") String id);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerAdminAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerAdminAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerAdminAsyncApi.java
deleted file mode 100644
index d15c925..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerAdminAsyncApi.java
+++ /dev/null
@@ -1,174 +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.openstack.nova.v2_0.extensions;
-
-import javax.inject.Named;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
-import org.jclouds.fallbacks.MapHttp4xxCodesToExceptions;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.nova.v2_0.domain.BackupType;
-import org.jclouds.openstack.nova.v2_0.functions.ParseImageIdFromLocationHeader;
-import org.jclouds.openstack.nova.v2_0.options.CreateBackupOfServerOptions;
-import org.jclouds.openstack.v2_0.ServiceType;
-import org.jclouds.openstack.v2_0.services.Extension;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.Payload;
-import org.jclouds.rest.annotations.PayloadParam;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.ResponseParser;
-import org.jclouds.rest.annotations.WrapWith;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provide access to Admin Server Actions via REST API
- *
- * @see org.jclouds.openstack.nova.v2_0.extensions.ServerAdminApi
- */
-@Beta
-@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.ADMIN_ACTIONS)
-@RequestFilters(AuthenticateRequest.class)
-@Path("/servers/{id}/action")
-public interface ServerAdminAsyncApi {
-
-   /**
-    * @see ServerAdminApi#suspend(String)
-    */
-   @Named("serveradmin:suspend")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("{\"suspend\":null}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> suspend(@PathParam("id") String id);
-
-   /**
-    * @see ServerAdminApi#resume(String)
-    */
-   @Named("serveradmin:resume")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("{\"resume\":null}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> resume(@PathParam("id") String id);
-
-   /**
-    * @see ServerAdminApi#migrate(String)
-    */
-   @Named("serveradmin:migrate")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("{\"migrate\":null}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> migrate(@PathParam("id") String id);
-
-   /**
-    * @see ServerAdminApi#lock(String)
-    */
-   @Named("serveradmin:lock")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("{\"lock\":null}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> lock(@PathParam("id") String id);
-
-   /**
-    * @see ServerAdminApi#unlock(String)
-    */
-   @Named("serveradmin:unlock")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("{\"unlock\":null}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> unlock(@PathParam("id") String id);
-
-   /**
-    * @see ServerAdminApi#resetNetwork(String)
-    */
-   @Named("serveradmin:resetnetwork")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("{\"resetNetwork\":null}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> resetNetwork(@PathParam("id") String id);
-
-   /**
-    * @see ServerAdminApi#createBackup
-    */
-   @Named("serveradmin:createbackup")
-   @POST
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Produces(MediaType.APPLICATION_JSON)
-   @WrapWith("createBackup")
-   @Fallback(MapHttp4xxCodesToExceptions.class)
-   @ResponseParser(ParseImageIdFromLocationHeader.class)
-   ListenableFuture<String> createBackup(@PathParam("id") String id,
-                                                  @PayloadParam("name") String imageName,
-                                                  @PayloadParam("backup_type") BackupType backupType,
-                                                  @PayloadParam("rotation") int rotation,
-                                                  CreateBackupOfServerOptions... options);
-
-   /**
-    * @see ServerAdminApi#pause(String)
-    */
-   @Named("serveradmin:pause")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("{\"pause\":null}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> pause(@PathParam("id") String id);
-
-   /**
-    * @see ServerAdminApi#unpause(String)
-    */
-   @Named("serveradmin:unpause")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("{\"unpause\":null}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> unpause(@PathParam("id") String id);
-
-   /**
-    * @see ServerAdminApi#injectNetworkInfo(String)
-    */
-   @Named("serveradmin:injectnetwork")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Payload("{\"injectNetworkInfo\":null}")
-   @Fallback(FalseOnNotFoundOr404.class)
-   ListenableFuture<Boolean> injectNetworkInfo(@PathParam("id") String id);
-
-   /**
-    * @see ServerAdminApi#liveMigrate(String)
-    */
-   @Named("serveradmin:livemigrate")
-   @POST
-   @Produces(MediaType.APPLICATION_JSON)
-   @Fallback(FalseOnNotFoundOr404.class)
-   @WrapWith("os-migrateLive")
-   ListenableFuture<Boolean> liveMigrate(@PathParam("id") String id,
-                                               @PayloadParam("host") String host,
-                                               @PayloadParam("block_migration") boolean blockMigration,
-                                               @PayloadParam("disk_over_commit") boolean diskOverCommit);
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerWithSecurityGroupsApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerWithSecurityGroupsApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerWithSecurityGroupsApi.java
index c1ecf2a..02bebd5 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerWithSecurityGroupsApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerWithSecurityGroupsApi.java
@@ -16,33 +16,53 @@
  */
 package org.jclouds.openstack.nova.v2_0.extensions;
 
+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.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.ServerWithSecurityGroups;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
 
 import com.google.common.annotations.Beta;
 
 /**
- * Provides synchronous access to Server details including security group, referred to as the CREATESERVEREXT extension
- * in the nova documentation
+ * Provides access to the OpenStack Compute (Nova) Create Server extension API.
+ *
+ * This provides details including the security groups associated with a Server.
  * <p/>
- * NOTE: the equivalent to listServersInDetail() isn't available at the other end, so not extending ServerApi at this
- * time.
+ *
+ * NOTE: the equivalent to listServersInDetail() isn't available at the other end, so not
+ * extending ServerApi at this time.
  *
  * @see org.jclouds.openstack.nova.v2_0.features.ServerApi
- * @see ServerWithSecurityGroupsAsyncApi
- * @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.createserverext.html"/>
  */
 @Beta
 @Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.CREATESERVEREXT)
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/os-create-server-ext")
 public interface ServerWithSecurityGroupsApi {
-
    /**
     * Retrieve details of the specified server, including security groups
     *
     * @param id id of the server
     * @return server or null if not found
     */
-   ServerWithSecurityGroups get(String id);
-
+   @Named("server:get")
+   @GET
+   @SelectJson("server")
+   @Path("/{id}")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   ServerWithSecurityGroups get(@PathParam("id") String id);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerWithSecurityGroupsAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerWithSecurityGroupsAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerWithSecurityGroupsAsyncApi.java
deleted file mode 100644
index 4c68d57..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ServerWithSecurityGroupsAsyncApi.java
+++ /dev/null
@@ -1,61 +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.openstack.nova.v2_0.extensions;
-
-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.NullOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.nova.v2_0.domain.ServerWithSecurityGroups;
-import org.jclouds.openstack.v2_0.ServiceType;
-import org.jclouds.openstack.v2_0.services.Extension;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-
-import com.google.common.annotations.Beta;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides synchronous access to Servers with Security Groups.
- *
- * @see org.jclouds.openstack.nova.v2_0.features.ServerAsyncApi
- * @see ServerWithSecurityGroupsApi
- * @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.createserverext.html"/>
- */
-@Beta
-@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.CREATESERVEREXT)
-@RequestFilters(AuthenticateRequest.class)
-public interface ServerWithSecurityGroupsAsyncApi {
-
-   /**
-    * @see ServerWithSecurityGroupsApi#get(String)
-    */
-   @Named("server:get")
-   @GET
-   @SelectJson("server")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/os-create-server-ext/{id}")
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<? extends ServerWithSecurityGroups> get(@PathParam("id") String id);
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SimpleTenantUsageApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SimpleTenantUsageApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SimpleTenantUsageApi.java
index 0db733e..46dff34 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SimpleTenantUsageApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SimpleTenantUsageApi.java
@@ -16,34 +16,57 @@
  */
 package org.jclouds.openstack.nova.v2_0.extensions;
 
+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.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.SimpleTenantUsage;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.FluentIterable;
 
 /**
- * Provides asynchronous access to Simple Tenant Usage via the REST API.
- * <p/>
- *
- * @see SimpleTenantUsageAsyncApi
+ * Provides access to the OpenStack Compute (Nova) Simple Tenant Usage extension API.
  */
 @Beta
 @Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SIMPLE_TENANT_USAGE)
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/os-simple-tenant-usage")
 public interface SimpleTenantUsageApi {
-
    /**
-    * Retrieve tenant_usage for all tenants
+    * Retrieve tenant usage for all tenants.
     *
     * @return the set of TenantUsage reports
     */
-   FluentIterable<? extends SimpleTenantUsage> list();
+   @Named("tenantUsage:list")
+   @GET
+   @SelectJson("tenant_usages")
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<SimpleTenantUsage> list();
 
    /**
     * Retrieve tenant_usage for a specified tenant
     *
     * @return the requested tenant usage
     */
-   SimpleTenantUsage get(String tenantId);
+   @Named("tenantUsage:get")
+   @GET
+   @Path("/{id}")
+   @SelectJson("tenant_usage")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   SimpleTenantUsage get(@PathParam("id") String tenantId);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SimpleTenantUsageAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SimpleTenantUsageAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SimpleTenantUsageAsyncApi.java
deleted file mode 100644
index 33ab475..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/SimpleTenantUsageAsyncApi.java
+++ /dev/null
@@ -1,76 +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.openstack.nova.v2_0.extensions;
-
-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.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.nova.v2_0.domain.SimpleTenantUsage;
-import org.jclouds.openstack.v2_0.ServiceType;
-import org.jclouds.openstack.v2_0.services.Extension;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.FluentIterable;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to Simple Tenant Usage via the REST API.
- * <p/>
- *
- * @see SimpleTenantUsageApi
- * @see <a href= "http://docs.openstack.org/api/openstack-compute/2/content/Extensions-d1e1444.html" />
- * @see <a href="http://nova.openstack.org/api_ext" />
- * @see <a href="http://nova.openstack.org/api/nova.api.openstack.compute.contrib.simple_tenant_usage.html" />
- */
-@Beta
-@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.SIMPLE_TENANT_USAGE)
-@RequestFilters(AuthenticateRequest.class)
-public interface SimpleTenantUsageAsyncApi {
-
-   /**
-    * @see SimpleTenantUsageApi#list()
-    */
-   @Named("tenantusage:list")
-   @GET
-   @Path("/os-simple-tenant-usage")
-   @SelectJson("tenant_usages")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<? extends FluentIterable<? extends SimpleTenantUsage>> list();
-
-   /**
-    * @see SimpleTenantUsageApi#get(String)
-    */
-   @Named("tenantusage:get")
-   @GET
-   @Path("/os-simple-tenant-usage/{id}")
-   @SelectJson("tenant_usage")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Fallback(NullOnNotFoundOr404.class)
-   ListenableFuture<? extends SimpleTenantUsage> get(@PathParam("id") String tenantId);
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VirtualInterfaceApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VirtualInterfaceApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VirtualInterfaceApi.java
index e74abc9..a0f8833 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VirtualInterfaceApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VirtualInterfaceApi.java
@@ -16,27 +16,44 @@
  */
 package org.jclouds.openstack.nova.v2_0.extensions;
 
+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.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.VirtualInterface;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.FluentIterable;
 
 /**
- * Provides synchronous access to Virtual Interface features (VIFs).
- * 
- * @see VirtualInterfaceAsyncApi
+ * Provides access to the OpenStack Compute (Nova) Virtual Interface (VIFs) extension API.
  */
 @Beta
 @Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VIRTUAL_INTERFACES)
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/servers")
 public interface VirtualInterfaceApi {
-
    /**
     * Returns the list of Virtual Interfaces for a given instance.
     *
-    * @return the list of snapshots
+    * @return the list of virtual interfaces
     */
-   FluentIterable<? extends VirtualInterface> listOnServer(String serverId);   
-
+   @Named("virtualInterface:list")
+   @GET
+   @Path("/{id}/os-virtual-interfaces")
+   @SelectJson("virtual_interfaces")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<VirtualInterface> listOnServer(@PathParam("id") String serverId);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VirtualInterfaceAsyncApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VirtualInterfaceAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VirtualInterfaceAsyncApi.java
deleted file mode 100644
index 9d1a753..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VirtualInterfaceAsyncApi.java
+++ /dev/null
@@ -1,58 +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.openstack.nova.v2_0.extensions;
-
-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.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
-import org.jclouds.openstack.nova.v2_0.domain.VirtualInterface;
-import org.jclouds.openstack.v2_0.ServiceType;
-import org.jclouds.openstack.v2_0.services.Extension;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.annotations.RequestFilters;
-import org.jclouds.rest.annotations.SelectJson;
-
-import com.google.common.annotations.Beta;
-import com.google.common.collect.FluentIterable;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * Provides asynchronous access to Virtual Interface features (VIFs).
- * 
- * @see VirtualInterfaceApi
- */
-@Beta
-@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VIRTUAL_INTERFACES)
-@RequestFilters(AuthenticateRequest.class)
-public interface VirtualInterfaceAsyncApi {
-   /**
-    * @see VirtualInterfaceApi#listOnServer(String)
-    */
-   @Named("virtualinterface:list")
-   @GET
-   @SelectJson("virtual_interfaces")
-   @Consumes(MediaType.APPLICATION_JSON)
-   @Path("/servers/{server_id}/os-virtual-interfaces")
-   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
-   ListenableFuture<? extends FluentIterable<? extends VirtualInterface>> listOnServer(@PathParam("server_id") String serverId);
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/801aecaf/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeApi.java
index 31178f8..485fb09 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeApi.java
@@ -16,6 +16,21 @@
  */
 package org.jclouds.openstack.nova.v2_0.extensions;
 
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.Volume;
 import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
 import org.jclouds.openstack.nova.v2_0.domain.VolumeSnapshot;
@@ -23,124 +38,210 @@ import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions;
 import org.jclouds.openstack.nova.v2_0.options.CreateVolumeSnapshotOptions;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
+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.SelectJson;
+import org.jclouds.rest.annotations.WrapWith;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.FluentIterable;
 
 /**
- * Provides synchronous access to Volumes.
- * <p/>
- * 
- * @see VolumeAsyncApi
- * @see org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi
+ * Provides access to the OpenStack Compute (Nova) Volume extension API.
  */
 @Beta
 @Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.VOLUMES)
+@RequestFilters(AuthenticateRequest.class)
+@Consumes(MediaType.APPLICATION_JSON)
 public interface VolumeApi {
    /**
     * Returns a summary list of snapshots.
     *
     * @return the list of snapshots
     */
-   FluentIterable<? extends Volume> list();
+   @Named("volume:list")
+   @GET
+   @Path("/os-volumes")
+   @SelectJson("volumes")
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<Volume> list();
 
    /**
     * Returns a detailed list of volumes.
     *
     * @return the list of volumes.
     */
-   FluentIterable<? extends Volume> listInDetail();
+   @Named("volume:list")
+   @GET
+   @Path("/os-volumes/detail")
+   @SelectJson("volumes")
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<Volume> listInDetail();
 
    /**
     * Return data about the given volume.
     *
     * @return details of a specific snapshot.
     */
-   Volume get(String volumeId);
+   @Named("volume:get")
+   @GET
+   @Path("/os-volumes/{id}")
+   @SelectJson("volume")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Volume get(@PathParam("id") String volumeId);
 
    /**
     * Creates a new Snapshot
     *
     * @return the new Snapshot
     */
-   Volume create(int sizeGB, CreateVolumeOptions... options);
+   @Named("volume:create")
+   @POST
+   @Path("/os-volumes")
+   @SelectJson("volume")
+   @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(CreateVolumeOptions.class)
+   Volume create(@PayloadParam("size") int sizeGB, CreateVolumeOptions... options);
 
    /**
     * Delete a snapshot.
     *
     * @return true if successful
     */
-   boolean delete(String volumeId);
-   
+   @Named("volume:delete")
+   @DELETE
+   @Path("/os-volumes/{volumeId}")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean delete(@PathParam("volumeId") String volumeId);
+
    /**
     * List volume attachments for a given instance.
-    * 
+    *
     * @return all Floating IPs
     * @deprecated To be removed in jclouds 1.7
     * @see VolumeAttachmentApi#listAttachmentsOnServer(String)
     */
-   @Deprecated FluentIterable<? extends VolumeAttachment> listAttachmentsOnServer(String serverId);
+   @Deprecated
+   @Named("volume:listAttachments")
+   @GET
+   @Path("/servers/{id}/os-volume_attachments")
+   @SelectJson("volumeAttachments")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<VolumeAttachment> listAttachmentsOnServer(@PathParam("id") String serverId);
 
    /**
     * Get a specific attached volume.
-    * 
+    *
     * @return data about the given volume attachment.
     * @deprecated To be removed in jclouds 1.7
     * @see VolumeAttachmentApi#getAttachmentForVolumeOnServer(String, String)
     */
-   @Deprecated VolumeAttachment getAttachmentForVolumeOnServer(String volumeId, String serverId);
+   @Deprecated
+   @Named("volume:getAttachments")
+   @GET
+   @Path("/servers/{serverId}/os-volume_attachments/{id}")
+   @SelectJson("volumeAttachment")
+   @Consumes(MediaType.APPLICATION_JSON)
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   VolumeAttachment getAttachmentForVolumeOnServer(@PathParam("id") String volumeId,
+         @PathParam("serverId") String serverId);
 
    /**
     * Attach a volume to an instance
-    * 
+    *
     * @return data about the new volume attachment
     * @deprecated To be removed in jclouds 1.7
     * @see VolumeAttachmentApi#attachVolumeToServerAsDevice(String, String, String)
     */
-   @Deprecated VolumeAttachment attachVolumeToServerAsDevice(String volumeId, String serverId, String device);
+   @Deprecated
+   @Named("volume:attach")
+   @POST
+   @Path("/servers/{serverId}/os-volume_attachments")
+   @SelectJson("volumeAttachment")
+   @Produces(MediaType.APPLICATION_JSON)
+   @WrapWith("volumeAttachment")
+   VolumeAttachment attachVolumeToServerAsDevice(@PayloadParam("volumeId") String volumeId,
+         @PathParam("serverId") String serverId, @PayloadParam("device") String device);
 
    /**
     * Detach a Volume from an instance.
-    * 
+    *
     * @return true if successful
     * @deprecated To be removed in jclouds 1.7
     * @see VolumeAttachmentApi#detachVolumeFromServer(String, String)
     */
-   @Deprecated Boolean detachVolumeFromServer(String server_id, String volumeId);
+   @Deprecated
+   @Named("volume:detach")
+   @DELETE
+   @Path("/servers/{serverId}/os-volume_attachments/{id}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   Boolean detachVolumeFromServer(@PathParam("id") String volumeId,
+         @PathParam("serverId") String serverId);
 
    /**
     * Returns a summary list of snapshots.
     *
     * @return the list of snapshots
     */
-   FluentIterable<? extends VolumeSnapshot> listSnapshots();
+   @Named("volume:listSnapshots")
+   @GET
+   @Path("/os-snapshots")
+   @SelectJson("snapshots")
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<VolumeSnapshot> listSnapshots();
 
    /**
     * Returns a summary list of snapshots.
     *
     * @return the list of snapshots
     */
-   FluentIterable<? extends VolumeSnapshot> listSnapshotsInDetail();
+   @Named("volume:listSnapshots")
+   @GET
+   @Path("/os-snapshots/detail")
+   @SelectJson("snapshots")
+   @Fallback(EmptyFluentIterableOnNotFoundOr404.class)
+   FluentIterable<VolumeSnapshot> listSnapshotsInDetail();
 
    /**
     * Return data about the given snapshot.
     *
     * @return details of a specific snapshot.
     */
-   VolumeSnapshot getSnapshot(String snapshotId);
+   @Named("volume:getSnapshot")
+   @GET
+   @Path("/os-snapshots/{id}")
+   @SelectJson("snapshot")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   VolumeSnapshot getSnapshot(@PathParam("id") String snapshotId);
 
    /**
-    * Creates a new Snapshot
+    * Creates a new Snapshot.
     *
     * @return the new Snapshot
     */
-   VolumeSnapshot createSnapshot(String volumeId, CreateVolumeSnapshotOptions... options);
+   @Named("volume:createSnapshot")
+   @POST
+   @Path("/os-snapshots")
+   @SelectJson("snapshot")
+   @Produces(MediaType.APPLICATION_JSON)
+   @MapBinder(CreateVolumeSnapshotOptions.class)
+   VolumeSnapshot createSnapshot(@PayloadParam("volume_id") String volumeId, CreateVolumeSnapshotOptions... options);
 
    /**
     * Delete a snapshot.
     *
     * @return true if successful
     */
-   boolean deleteSnapshot(String snapshotId);
-   
+   @Named("volume:deleteSnapshot")
+   @DELETE
+   @Path("/os-snapshots/{id}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean deleteSnapshot(@PathParam("id") String snapshotId);
 }