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/08/13 18:59:50 UTC

[11/12] Prefer Regions to Zones in OpenStack APIs

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApi.java
index 9f8d302..63fb5ab 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApi.java
@@ -20,8 +20,8 @@ import java.io.Closeable;
 import java.util.Set;
 
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.location.Zone;
-import org.jclouds.location.functions.ZoneToEndpoint;
+import org.jclouds.location.Region;
+import org.jclouds.location.functions.RegionToEndpoint;
 import org.jclouds.openstack.nova.v2_0.extensions.AvailabilityZoneApi;
 import org.jclouds.openstack.nova.v2_0.extensions.ConsolesApi;
 import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsApi;
@@ -49,156 +49,413 @@ import com.google.common.base.Optional;
 import com.google.inject.Provides;
 
 /**
- * Provides access to the OpenStack Compute (Nova) API.
+ * Provides access to the OpenStack Compute (Nova) v2 API.
  * <p/>
  *
  */
 public interface NovaApi extends Closeable {
    /**
     *
+    * @return the Region codes configured
+    */
+   @Provides
+   @Region
+   Set<String> getConfiguredRegions();
+
+   /**
+    * Provides access to Server features.
+    */
+   @Delegate
+   ServerApi getServerApi(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Flavor features.
+    */
+   @Delegate
+   FlavorApi getFlavorApi(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Extension features.
+    */
+   @Delegate
+   ExtensionApi getExtensionApi(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Image features.
+    */
+   @Delegate
+   ImageApi getImageApi(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Availability Zone features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends AvailabilityZoneApi> getAvailabilityZoneApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Floating IP features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends FloatingIPApi> getFloatingIPApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Security Group features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends SecurityGroupApi> getSecurityGroupApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Key Pair features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends KeyPairApi> getKeyPairApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Host Administration features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends HostAdministrationApi> getHostAdministrationApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Simple Tenant Usage features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends SimpleTenantUsageApi> getSimpleTenantUsageApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Virtual Interface features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends VirtualInterfaceApi> getVirtualInterfaceApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Server Extra Data features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends ServerWithSecurityGroupsApi> getServerWithSecurityGroupsApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Server Admin Actions features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends ServerAdminApi> getServerAdminApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Aggregate features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends HostAggregateApi> getHostAggregateApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Flavor extra specs features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends FlavorExtraSpecsApi> getFlavorExtraSpecsApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Quota features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends QuotaApi> getQuotaApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Volume features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends VolumeApi> getVolumeApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Volume Attachment features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends VolumeAttachmentApi> getVolumeAttachmentApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Volume Type features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends VolumeTypeApi> getVolumeTypeApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
+    * Provides access to Console features.
+    *
+    * <h3>NOTE</h3>
+    * This API is an extension that may or may not be present in your OpenStack cloud. Use the Optional return type
+    * to determine if it is present.
+    */
+   @Delegate
+   Optional<? extends ConsolesApi> getConsolesApi(
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
+
+   /**
     * @return the Zone codes configured
+    * @deprecated Please use {@link #getConfiguredRegions()} as this method will be removed in jclouds 3.0.
     */
+   @Deprecated
    @Provides
-   @Zone
+   @Region
    Set<String> getConfiguredZones();
 
    /**
     * Provides access to Server features.
+    * @deprecated Please use {@link #getServerApi(String)} as this method will be removed in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    ServerApi getServerApiForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Flavor features.
+    * @deprecated Please use {@link #getFlavorApi(String)} as this method will be removed in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    FlavorApi getFlavorApiForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Extension features.
+    * @deprecated Please use {@link #getExtensionApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    ExtensionApi getExtensionApiForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Image features.
+    * @deprecated Please use {@link #getImageApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    ImageApi getImageApiForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
-
-   /**
-    * Provides access to availability zone features
-    */
-   @Delegate
-   Optional<? extends AvailabilityZoneApi> getAvailabilityZoneApi(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Floating IP features.
+    * @deprecated Please use {@link #getFloatingIPApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends FloatingIPApi> getFloatingIPExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Security Group features.
+    * @deprecated Please use {@link #getSecurityGroupApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends SecurityGroupApi> getSecurityGroupExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Key Pair features.
+    * @deprecated Please use {@link #getKeyPairApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends KeyPairApi> getKeyPairExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Host Administration features.
+    * @deprecated Please use {@link #getHostAdministrationApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends HostAdministrationApi> getHostAdministrationExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Simple Tenant Usage features.
+    * @deprecated Please use {@link #getSimpleTenantUsageApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends SimpleTenantUsageApi> getSimpleTenantUsageExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Virtual Interface features.
+    * @deprecated Please use {@link #getVirtualInterfaceApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends VirtualInterfaceApi> getVirtualInterfaceExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Server Extra Data features.
+    * @deprecated Please use {@link #getServerWithSecurityGroupsApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends ServerWithSecurityGroupsApi> getServerWithSecurityGroupsExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Server Admin Actions features.
+    * @deprecated Please use {@link #getServerAdminApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends ServerAdminApi> getServerAdminExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Aggregate features.
+    * @deprecated Please use {@link #getHostAggregateApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends HostAggregateApi> getHostAggregateExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Flavor extra specs features.
+    * @deprecated Please use {@link #getFlavorExtraSpecsApi(String)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends FlavorExtraSpecsApi> getFlavorExtraSpecsExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Quota features.
+    * @deprecated Please use {@link #getQuotaApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends QuotaApi> getQuotaExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Volume features.
+    * @deprecated Please use {@link #getVolumeApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends VolumeApi> getVolumeExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Volume Attachment features.
+    * @deprecated Please use {@link #getVolumeAttachmentApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends VolumeAttachmentApi> getVolumeAttachmentExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides access to Volume Type features.
+    * @deprecated Please use {@link #getVolumeTypeApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends VolumeTypeApi> getVolumeTypeExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 
    /**
     * Provides synchronous access to Console features.
+    * @deprecated Please use {@link #getConsolesApi(String region)} as this method will be removed
+    *             in jclouds 3.0.
     */
+   @Deprecated
    @Delegate
    Optional<? extends ConsolesApi> getConsolesExtensionForZone(
-         @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+         @EndpointParam(parser = RegionToEndpoint.class) @Nullable String zone);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApiMetadata.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApiMetadata.java
index 4dfd401..be37fe7 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApiMetadata.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApiMetadata.java
@@ -31,7 +31,7 @@ import org.jclouds.compute.ComputeServiceContext;
 import org.jclouds.openstack.keystone.v2_0.config.AuthenticationApiModule;
 import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
 import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ZoneModule;
+import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
 import org.jclouds.openstack.nova.v2_0.compute.config.NovaComputeServiceContextModule;
 import org.jclouds.openstack.nova.v2_0.config.NovaHttpApiModule;
 import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
@@ -92,7 +92,7 @@ public class NovaApiMetadata extends BaseHttpApiMetadata<NovaApi>  {
          .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
                                      .add(AuthenticationApiModule.class)
                                      .add(KeystoneAuthenticationModule.class)
-                                     .add(ZoneModule.class)
+                                     .add(RegionModule.class)
                                      .add(NovaParserModule.class)
                                      .add(NovaHttpApiModule.class)
                                      .add(NovaComputeServiceContextModule.class).build());

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java
index 163bbe4..6586395 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeService.java
@@ -61,8 +61,8 @@ import org.jclouds.openstack.nova.v2_0.NovaApi;
 import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
 import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
 import org.jclouds.openstack.nova.v2_0.domain.SecurityGroup;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
 import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
 import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
 import org.jclouds.openstack.nova.v2_0.predicates.SecurityGroupPredicates;
@@ -81,9 +81,9 @@ import com.google.common.util.concurrent.ListeningExecutorService;
 @Singleton
 public class NovaComputeService extends BaseComputeService {
    protected final NovaApi novaApi;
-   protected final LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap;
-   protected final LoadingCache<ZoneAndName, KeyPair> keyPairCache;
-   protected final Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByZoneId;
+   protected final LoadingCache<RegionAndName, SecurityGroupInRegion> securityGroupMap;
+   protected final LoadingCache<RegionAndName, KeyPair> keyPairCache;
+   protected final Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByRegionId;
    protected final GroupNamingConvention.Factory namingConvention;
 
    @Inject
@@ -102,9 +102,9 @@ public class NovaComputeService extends BaseComputeService {
             RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
             PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
             @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, NovaApi novaApi,
-            LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap,
-            LoadingCache<ZoneAndName, KeyPair> keyPairCache,
-            Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByZoneId,
+            LoadingCache<RegionAndName, SecurityGroupInRegion> securityGroupMap,
+            LoadingCache<RegionAndName, KeyPair> keyPairCache,
+            Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByRegionId,
             GroupNamingConvention.Factory namingConvention, Optional<ImageExtension> imageExtension,
             Optional<SecurityGroupExtension> securityGroupExtension) {
       super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy,
@@ -115,53 +115,53 @@ public class NovaComputeService extends BaseComputeService {
       this.novaApi = checkNotNull(novaApi, "novaApi");
       this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
       this.keyPairCache = checkNotNull(keyPairCache, "keyPairCache");
-      this.orphanedGroupsByZoneId = checkNotNull(orphanedGroupsByZoneId, "orphanedGroupsByZoneId");
+      this.orphanedGroupsByRegionId = checkNotNull(orphanedGroupsByRegionId, "orphanedGroupsByRegionId");
       this.namingConvention = checkNotNull(namingConvention, "namingConvention");
    }
 
    @Override
    protected void cleanUpIncidentalResourcesOfDeadNodes(Set<? extends NodeMetadata> deadNodes) {
-      Multimap<String, String> zoneToZoneAndGroupNames = orphanedGroupsByZoneId.apply(deadNodes);
-      for (Map.Entry<String, Collection<String>> entry : zoneToZoneAndGroupNames.asMap().entrySet()) {
-         cleanOrphanedGroupsInZone(ImmutableSet.copyOf(entry.getValue()), entry.getKey());
+      Multimap<String, String> regionToRegionAndGroupNames = orphanedGroupsByRegionId.apply(deadNodes);
+      for (Map.Entry<String, Collection<String>> entry : regionToRegionAndGroupNames.asMap().entrySet()) {
+         cleanOrphanedGroupsInRegion(ImmutableSet.copyOf(entry.getValue()), entry.getKey());
       }
    }
 
-   protected void cleanOrphanedGroupsInZone(Set<String> groups, String zoneId) {
-      cleanupOrphanedSecurityGroupsInZone(groups, zoneId);
-      cleanupOrphanedKeyPairsInZone(groups, zoneId);
+   protected void cleanOrphanedGroupsInRegion(Set<String> groups, String regionId) {
+      cleanupOrphanedSecurityGroupsInRegion(groups, regionId);
+      cleanupOrphanedKeyPairsInRegion(groups, regionId);
    }
 
-   private void cleanupOrphanedSecurityGroupsInZone(Set<String> groups, String zoneId) {
-      Optional<? extends SecurityGroupApi> securityGroupApi = novaApi.getSecurityGroupExtensionForZone(zoneId);
+   private void cleanupOrphanedSecurityGroupsInRegion(Set<String> groups, String regionId) {
+      Optional<? extends SecurityGroupApi> securityGroupApi = novaApi.getSecurityGroupApi(regionId);
       if (securityGroupApi.isPresent()) {
          for (String group : groups) {
             for (SecurityGroup securityGroup : Iterables.filter(securityGroupApi.get().list(),
                      SecurityGroupPredicates.nameMatches(namingConvention.create().containsGroup(group)))) {
-               ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, securityGroup.getName());
-               logger.debug(">> deleting securityGroup(%s)", zoneAndName);
+               RegionAndName regionAndName = RegionAndName.fromRegionAndName(regionId, securityGroup.getName());
+               logger.debug(">> deleting securityGroup(%s)", regionAndName);
                securityGroupApi.get().delete(securityGroup.getId());
                // TODO: test this clear happens
-               securityGroupMap.invalidate(zoneAndName);
-               logger.debug("<< deleted securityGroup(%s)", zoneAndName);
+               securityGroupMap.invalidate(regionAndName);
+               logger.debug("<< deleted securityGroup(%s)", regionAndName);
             }
          }
       }
    }
 
-   private void cleanupOrphanedKeyPairsInZone(Set<String> groups, String zoneId) {
-      Optional<? extends KeyPairApi> keyPairApi = novaApi.getKeyPairExtensionForZone(zoneId);
+   private void cleanupOrphanedKeyPairsInRegion(Set<String> groups, String regionId) {
+      Optional<? extends KeyPairApi> keyPairApi = novaApi.getKeyPairApi(regionId);
       if (keyPairApi.isPresent()) {
          for (String group : groups) {
             for (KeyPair pair : keyPairApi.get().list().filter(nameMatches(namingConvention.create().containsGroup(group)))) {
-               ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, pair.getName());
-               logger.debug(">> deleting keypair(%s)", zoneAndName);
+               RegionAndName regionAndName = RegionAndName.fromRegionAndName(regionId, pair.getName());
+               logger.debug(">> deleting keypair(%s)", regionAndName);
                keyPairApi.get().delete(pair.getName());
                // TODO: test this clear happens
-               keyPairCache.invalidate(zoneAndName);
-               logger.debug("<< deleted keypair(%s)", zoneAndName);
+               keyPairCache.invalidate(regionAndName);
+               logger.debug("<< deleted keypair(%s)", regionAndName);
             }
-            keyPairCache.invalidate(ZoneAndName.fromZoneAndName(zoneId,
+            keyPairCache.invalidate(RegionAndName.fromRegionAndName(regionId,
                      namingConvention.create().sharedNameForGroup(group)));
          }
       }
@@ -174,7 +174,5 @@ public class NovaComputeService extends BaseComputeService {
    public NovaTemplateOptions templateOptions() {
       return NovaTemplateOptions.class.cast(super.templateOptions());
    }
-   
-   
 
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceAdapter.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceAdapter.java
index 2361899..f0c973b 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceAdapter.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceAdapter.java
@@ -34,22 +34,23 @@ import org.jclouds.compute.domain.Template;
 import org.jclouds.compute.reference.ComputeServiceConstants;
 import org.jclouds.domain.Location;
 import org.jclouds.domain.LoginCredentials;
-import org.jclouds.location.Zone;
+import org.jclouds.location.Region;
 import org.jclouds.logging.Logger;
 import org.jclouds.openstack.nova.v2_0.NovaApi;
 import org.jclouds.openstack.nova.v2_0.compute.functions.RemoveFloatingIpFromNodeAndDeallocate;
 import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
+import org.jclouds.openstack.nova.v2_0.compute.strategy.ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet;
 import org.jclouds.openstack.nova.v2_0.domain.Flavor;
 import org.jclouds.openstack.nova.v2_0.domain.Image;
 import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
 import org.jclouds.openstack.nova.v2_0.domain.RebootType;
 import org.jclouds.openstack.nova.v2_0.domain.Server;
 import org.jclouds.openstack.nova.v2_0.domain.ServerCreated;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.FlavorInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ImageInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ServerInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.FlavorInRegion;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.ImageInRegion;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndId;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.ServerInRegion;
 import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions;
 import org.jclouds.openstack.nova.v2_0.predicates.ImagePredicates;
 
@@ -67,23 +68,23 @@ import com.google.common.collect.ImmutableSet.Builder;
  * model to the computeService generic domain model.
  */
 public class NovaComputeServiceAdapter implements
-         ComputeServiceAdapter<ServerInZone, FlavorInZone, ImageInZone, Location> {
+         ComputeServiceAdapter<ServerInRegion, FlavorInRegion, ImageInRegion, Location> {
 
    @Resource
    @Named(ComputeServiceConstants.COMPUTE_LOGGER)
    protected Logger logger = Logger.NULL;
 
    protected final NovaApi novaApi;
-   protected final Supplier<Set<String>> zoneIds;
+   protected final Supplier<Set<String>> regionIds;
    protected final RemoveFloatingIpFromNodeAndDeallocate removeFloatingIpFromNodeAndDeallocate;
-   protected final LoadingCache<ZoneAndName, KeyPair> keyPairCache;
+   protected final LoadingCache<RegionAndName, KeyPair> keyPairCache;
 
    @Inject
-   public NovaComputeServiceAdapter(NovaApi novaApi, @Zone Supplier<Set<String>> zoneIds,
+   public NovaComputeServiceAdapter(NovaApi novaApi, @Region Supplier<Set<String>> regionIds,
             RemoveFloatingIpFromNodeAndDeallocate removeFloatingIpFromNodeAndDeallocate,
-            LoadingCache<ZoneAndName, KeyPair> keyPairCache) {
+            LoadingCache<RegionAndName, KeyPair> keyPairCache) {
       this.novaApi = checkNotNull(novaApi, "novaApi");
-      this.zoneIds = checkNotNull(zoneIds, "zoneIds");
+      this.regionIds = checkNotNull(regionIds, "regionIds");
       this.removeFloatingIpFromNodeAndDeallocate = checkNotNull(removeFloatingIpFromNodeAndDeallocate,
                "removeFloatingIpFromNodeAndDeallocate");
       this.keyPairCache = checkNotNull(keyPairCache, "keyPairCache");
@@ -95,7 +96,7 @@ public class NovaComputeServiceAdapter implements
     * done so.
     */
    @Override
-   public NodeAndInitialCredentials<ServerInZone> createNodeWithGroupEncodedIntoName(String group, String name,
+   public NodeAndInitialCredentials<ServerInRegion> createNodeWithGroupEncodedIntoName(String group, String name,
             Template template) {
 
       LoginCredentials.Builder credentialsBuilder = LoginCredentials.builder();
@@ -118,40 +119,40 @@ public class NovaComputeServiceAdapter implements
       Optional<String> privateKey = Optional.absent();
       if (templateOptions.getKeyPairName() != null) {
          options.keyPairName(templateOptions.getKeyPairName());
-         KeyPair keyPair = keyPairCache.getIfPresent(ZoneAndName.fromZoneAndName(template.getLocation().getId(), templateOptions.getKeyPairName()));
+         KeyPair keyPair = keyPairCache.getIfPresent(RegionAndName.fromRegionAndName(template.getLocation().getId(), templateOptions.getKeyPairName()));
          if (keyPair != null && keyPair.getPrivateKey() != null) {
             privateKey = Optional.of(keyPair.getPrivateKey());
             credentialsBuilder.privateKey(privateKey.get());
          }
       }
 
-      String zoneId = template.getLocation().getId();
+      String regionId = template.getLocation().getId();
       String imageId = template.getImage().getProviderId();
       String flavorId = template.getHardware().getProviderId();
 
-      logger.debug(">> creating new server zone(%s) name(%s) image(%s) flavor(%s) options(%s)", zoneId, name, imageId, flavorId, options);
-      ServerCreated lightweightServer = novaApi.getServerApiForZone(zoneId).create(name, imageId, flavorId, options);
-      Server server = novaApi.getServerApiForZone(zoneId).get(lightweightServer.getId());
+      logger.debug(">> creating new server region(%s) name(%s) image(%s) flavor(%s) options(%s)", regionId, name, imageId, flavorId, options);
+      ServerCreated lightweightServer = novaApi.getServerApi(regionId).create(name, imageId, flavorId, options);
+      Server server = novaApi.getServerApi(regionId).get(lightweightServer.getId());
 
       logger.trace("<< server(%s)", server.getId());
 
-      ServerInZone serverInZone = new ServerInZone(server, zoneId);
+      ServerInRegion serverInRegion = new ServerInRegion(server, regionId);
       if (!privateKey.isPresent() && lightweightServer.getAdminPass().isPresent())
          credentialsBuilder.password(lightweightServer.getAdminPass().get());
-      return new NodeAndInitialCredentials<ServerInZone>(serverInZone, serverInZone.slashEncode(), credentialsBuilder
+      return new NodeAndInitialCredentials<ServerInRegion>(serverInRegion, serverInRegion.slashEncode(), credentialsBuilder
                .build());
    }
 
    @Override
-   public Iterable<FlavorInZone> listHardwareProfiles() {
-      Builder<FlavorInZone> builder = ImmutableSet.builder();
-      for (final String zoneId : zoneIds.get()) {
-         builder.addAll(transform(novaApi.getFlavorApiForZone(zoneId).listInDetail().concat(),
-                  new Function<Flavor, FlavorInZone>() {
+   public Iterable<FlavorInRegion> listHardwareProfiles() {
+      Builder<FlavorInRegion> builder = ImmutableSet.builder();
+      for (final String regionId : regionIds.get()) {
+         builder.addAll(transform(novaApi.getFlavorApi(regionId).listInDetail().concat(),
+                  new Function<Flavor, FlavorInRegion>() {
 
                      @Override
-                     public FlavorInZone apply(Flavor arg0) {
-                        return new FlavorInZone(arg0, zoneId);
+                     public FlavorInRegion apply(Flavor arg0) {
+                        return new FlavorInRegion(arg0, regionId);
                      }
 
                   }));
@@ -160,19 +161,19 @@ public class NovaComputeServiceAdapter implements
    }
 
    @Override
-   public Iterable<ImageInZone> listImages() {
-      Builder<ImageInZone> builder = ImmutableSet.builder();
-      Set<String> zones = zoneIds.get();
-      checkState(zones.size() > 0, "no zones found in supplier %s", zoneIds);
-      for (final String zoneId : zones) {
-         Set<? extends Image> images = novaApi.getImageApiForZone(zoneId).listInDetail().concat().toSet();
+   public Iterable<ImageInRegion> listImages() {
+      Builder<ImageInRegion> builder = ImmutableSet.builder();
+      Set<String> regions = regionIds.get();
+      checkState(regions.size() > 0, "no regions found in supplier %s", regionIds);
+      for (final String regionId : regions) {
+         Set<? extends Image> images = novaApi.getImageApi(regionId).listInDetail().concat().toSet();
          if (images.size() == 0) {
-            logger.debug("no images found in zone %s", zoneId);
+            logger.debug("no images found in region %s", regionId);
             continue;
          }
          Iterable<? extends Image> active = filter(images, ImagePredicates.statusEquals(Image.Status.ACTIVE));
          if (images.size() == 0) {
-            logger.debug("no images with status active in zone %s; non-active: %s", zoneId,
+            logger.debug("no images with status active in region %s; non-active: %s", regionId,
                      transform(active, new Function<Image, String>() {
 
                         @Override
@@ -184,11 +185,11 @@ public class NovaComputeServiceAdapter implements
                      }));
             continue;
          }
-         builder.addAll(transform(active, new Function<Image, ImageInZone>() {
+         builder.addAll(transform(active, new Function<Image, ImageInRegion>() {
 
             @Override
-            public ImageInZone apply(Image arg0) {
-               return new ImageInZone(arg0, zoneId);
+            public ImageInRegion apply(Image arg0) {
+               return new ImageInRegion(arg0, regionId);
             }
 
          }));
@@ -197,15 +198,15 @@ public class NovaComputeServiceAdapter implements
    }
 
    @Override
-   public Iterable<ServerInZone> listNodes() {
-      Builder<ServerInZone> builder = ImmutableSet.builder();
-      for (final String zoneId : zoneIds.get()) {
-         builder.addAll(novaApi.getServerApiForZone(zoneId).listInDetail().concat()
-                  .transform(new Function<Server, ServerInZone>() {
+   public Iterable<ServerInRegion> listNodes() {
+      Builder<ServerInRegion> builder = ImmutableSet.builder();
+      for (final String regionId : regionIds.get()) {
+         builder.addAll(novaApi.getServerApi(regionId).listInDetail().concat()
+                  .transform(new Function<Server, ServerInRegion>() {
 
                      @Override
-                     public ServerInZone apply(Server arg0) {
-                        return new ServerInZone(arg0, zoneId);
+                     public ServerInRegion apply(Server arg0) {
+                        return new ServerInRegion(arg0, regionId);
                      }
 
                   }));
@@ -214,11 +215,11 @@ public class NovaComputeServiceAdapter implements
    }
 
    @Override
-   public Iterable<ServerInZone> listNodesByIds(final Iterable<String> ids) {
-      return filter(listNodes(), new Predicate<ServerInZone>() {
+   public Iterable<ServerInRegion> listNodesByIds(final Iterable<String> ids) {
+      return filter(listNodes(), new Predicate<ServerInRegion>() {
 
             @Override
-            public boolean apply(ServerInZone server) {
+            public boolean apply(ServerInRegion server) {
                return contains(ids, server.slashEncode());
             }
          });
@@ -231,43 +232,43 @@ public class NovaComputeServiceAdapter implements
    }
 
    @Override
-   public ServerInZone getNode(String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
-      Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
-      return server == null ? null : new ServerInZone(server, zoneAndId.getZone());
+   public ServerInRegion getNode(String id) {
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
+      Server server = novaApi.getServerApi(regionAndId.getRegion()).get(regionAndId.getId());
+      return server == null ? null : new ServerInRegion(server, regionAndId.getRegion());
    }
 
    @Override
-   public ImageInZone getImage(String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
-      Image image = novaApi.getImageApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
-      return image == null ? null : new ImageInZone(image, zoneAndId.getZone());
+   public ImageInRegion getImage(String id) {
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
+      Image image = novaApi.getImageApi(regionAndId.getRegion()).get(regionAndId.getId());
+      return image == null ? null : new ImageInRegion(image, regionAndId.getRegion());
    }
 
    @Override
    public void destroyNode(String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
-      if (novaApi.getFloatingIPExtensionForZone(zoneAndId.getZone()).isPresent()) {
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
+      if (novaApi.getFloatingIPApi(regionAndId.getRegion()).isPresent()) {
          try {
-            removeFloatingIpFromNodeAndDeallocate.apply(zoneAndId);
+            removeFloatingIpFromNodeAndDeallocate.apply(regionAndId);
          } catch (RuntimeException e) {
             logger.warn(e, "<< error removing and deallocating ip from node(%s): %s", id, e.getMessage());
          }
       }
-      novaApi.getServerApiForZone(zoneAndId.getZone()).delete(zoneAndId.getId());
+      novaApi.getServerApi(regionAndId.getRegion()).delete(regionAndId.getId());
    }
 
    @Override
    public void rebootNode(String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
-      novaApi.getServerApiForZone(zoneAndId.getZone()).reboot(zoneAndId.getId(), RebootType.HARD);
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
+      novaApi.getServerApi(regionAndId.getRegion()).reboot(regionAndId.getId(), RebootType.HARD);
    }
 
    @Override
    public void resumeNode(String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
-      if (novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).isPresent()) {
-         novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).get().resume(zoneAndId.getId());
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
+      if (novaApi.getServerAdminApi(regionAndId.getRegion()).isPresent()) {
+         novaApi.getServerAdminApi(regionAndId.getRegion()).get().resume(regionAndId.getId());
       } else {
          throw new UnsupportedOperationException("resume requires installation of the Admin Actions extension");
       }
@@ -275,9 +276,9 @@ public class NovaComputeServiceAdapter implements
 
    @Override
    public void suspendNode(String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
-      if (novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).isPresent()) {
-         novaApi.getServerAdminExtensionForZone(zoneAndId.getZone()).get().suspend(zoneAndId.getId());
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
+      if (novaApi.getServerAdminApi(regionAndId.getRegion()).isPresent()) {
+         novaApi.getServerAdminApi(regionAndId.getRegion()).get().suspend(regionAndId.getId());
       } else {
          throw new UnsupportedOperationException("suspend requires installation of the Admin Actions extension");
       }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
index e070bdb..cabca59 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/config/NovaComputeServiceContextModule.java
@@ -52,14 +52,14 @@ import org.jclouds.openstack.nova.v2_0.compute.NovaComputeServiceAdapter;
 import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaImageExtension;
 import org.jclouds.openstack.nova.v2_0.compute.extensions.NovaSecurityGroupExtension;
 import org.jclouds.openstack.nova.v2_0.compute.functions.CreateSecurityGroupIfNeeded;
-import org.jclouds.openstack.nova.v2_0.compute.functions.FlavorInZoneToHardware;
-import org.jclouds.openstack.nova.v2_0.compute.functions.ImageInZoneToImage;
+import org.jclouds.openstack.nova.v2_0.compute.functions.FlavorInRegionToHardware;
+import org.jclouds.openstack.nova.v2_0.compute.functions.ImageInRegionToImage;
 import org.jclouds.openstack.nova.v2_0.compute.functions.ImageToOperatingSystem;
-import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupInZoneToSecurityGroup;
+import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupInRegionToSecurityGroup;
 import org.jclouds.openstack.nova.v2_0.compute.functions.NovaSecurityGroupToSecurityGroup;
-import org.jclouds.openstack.nova.v2_0.compute.functions.OrphanedGroupsByZoneId;
+import org.jclouds.openstack.nova.v2_0.compute.functions.OrphanedGroupsByRegionId;
 import org.jclouds.openstack.nova.v2_0.compute.functions.SecurityGroupRuleToIpPermission;
-import org.jclouds.openstack.nova.v2_0.compute.functions.ServerInZoneToNodeMetadata;
+import org.jclouds.openstack.nova.v2_0.compute.functions.ServerInRegionToNodeMetadata;
 import org.jclouds.openstack.nova.v2_0.compute.loaders.CreateUniqueKeyPair;
 import org.jclouds.openstack.nova.v2_0.compute.loaders.FindSecurityGroupOrCreate;
 import org.jclouds.openstack.nova.v2_0.compute.loaders.LoadFloatingIpsForInstance;
@@ -69,13 +69,13 @@ import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
 import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
 import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
 import org.jclouds.openstack.nova.v2_0.domain.Server;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.FlavorInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ImageInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ServerInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.FlavorInRegion;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.ImageInRegion;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.ServerInRegion;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndId;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
 import org.jclouds.openstack.nova.v2_0.predicates.FindSecurityGroupWithNameAndReturnTrue;
 
 import com.google.common.annotations.VisibleForTesting;
@@ -100,19 +100,19 @@ import com.google.inject.name.Names;
  * Module for building a compute service context for Nova
  */
 public class NovaComputeServiceContextModule extends
-         ComputeServiceAdapterContextModule<ServerInZone, FlavorInZone, ImageInZone, Location> {
+         ComputeServiceAdapterContextModule<ServerInRegion, FlavorInRegion, ImageInRegion, Location> {
 
    @SuppressWarnings("unchecked")
    @Override
    protected void configure() {
       super.configure();
-      bind(new TypeLiteral<ComputeServiceAdapter<ServerInZone, FlavorInZone, ImageInZone, Location>>() {
+      bind(new TypeLiteral<ComputeServiceAdapter<ServerInRegion, FlavorInRegion, ImageInRegion, Location>>() {
       }).to(NovaComputeServiceAdapter.class);
      
       bind(ComputeService.class).to(NovaComputeService.class);
       
-      bind(new TypeLiteral<Function<ServerInZone, NodeMetadata>>() {
-      }).to(ServerInZoneToNodeMetadata.class);
+      bind(new TypeLiteral<Function<ServerInRegion, NodeMetadata>>() {
+      }).to(ServerInRegionToNodeMetadata.class);
 
       bind(new TypeLiteral<Function<SecurityGroupRule, IpPermission>>() {
       }).to(SecurityGroupRuleToIpPermission.class);
@@ -120,19 +120,19 @@ public class NovaComputeServiceContextModule extends
       bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroup>>() {
       }).to(NovaSecurityGroupToSecurityGroup.class);
 
-      bind(new TypeLiteral<Function<SecurityGroupInZone, SecurityGroup>>() {
-      }).to(NovaSecurityGroupInZoneToSecurityGroup.class);
+      bind(new TypeLiteral<Function<SecurityGroupInRegion, SecurityGroup>>() {
+      }).to(NovaSecurityGroupInRegionToSecurityGroup.class);
 
       bind(new TypeLiteral<Function<Set<? extends NodeMetadata>,  Multimap<String, String>>>() {
-      }).to(OrphanedGroupsByZoneId.class);
+      }).to(OrphanedGroupsByRegionId.class);
 
-      bind(new TypeLiteral<Function<ImageInZone, Image>>() {
-      }).to(ImageInZoneToImage.class);
+      bind(new TypeLiteral<Function<ImageInRegion, Image>>() {
+      }).to(ImageInRegionToImage.class);
       bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v2_0.domain.Image, OperatingSystem>>() {
       }).to(ImageToOperatingSystem.class);
 
-      bind(new TypeLiteral<Function<FlavorInZone, Hardware>>() {
-      }).to(FlavorInZoneToHardware.class);
+      bind(new TypeLiteral<Function<FlavorInRegion, Hardware>>() {
+      }).to(FlavorInRegionToHardware.class);
 
       // we aren't converting location from a provider-specific type
       bind(new TypeLiteral<Function<Location, Location>>() {
@@ -140,19 +140,19 @@ public class NovaComputeServiceContextModule extends
 
       bind(TemplateOptions.class).to(NovaTemplateOptions.class);
 
-      bind(new TypeLiteral<CacheLoader<ZoneAndId, Iterable<? extends FloatingIP>>>() {
+      bind(new TypeLiteral<CacheLoader<RegionAndId, Iterable<? extends FloatingIP>>>() {
       }).annotatedWith(Names.named("FLOATINGIP")).to(LoadFloatingIpsForInstance.class);
 
-      bind(new TypeLiteral<Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>>() {
+      bind(new TypeLiteral<Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion>>() {
       }).to(CreateSecurityGroupIfNeeded.class);
 
-      bind(new TypeLiteral<CacheLoader<ZoneAndName, SecurityGroupInZone>>() {
+      bind(new TypeLiteral<CacheLoader<RegionAndName, SecurityGroupInRegion>>() {
       }).to(FindSecurityGroupOrCreate.class);
 
       bind(CreateNodesWithGroupEncodedIntoNameThenAddToSet.class).to(
                ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.class);
 
-      bind(new TypeLiteral<CacheLoader<ZoneAndName, KeyPair>>() {
+      bind(new TypeLiteral<CacheLoader<RegionAndName, KeyPair>>() {
       }).to(CreateUniqueKeyPair.class);
       
       bind(new TypeLiteral<ImageExtension>() {
@@ -174,15 +174,15 @@ public class NovaComputeServiceContextModule extends
    @Provides
    @Singleton
    @Named("FLOATINGIP")
-   protected LoadingCache<ZoneAndId, Iterable<? extends FloatingIP>> instanceToFloatingIps(
-            @Named("FLOATINGIP") CacheLoader<ZoneAndId, Iterable<? extends FloatingIP>> in) {
+   protected LoadingCache<RegionAndId, Iterable<? extends FloatingIP>> instanceToFloatingIps(
+            @Named("FLOATINGIP") CacheLoader<RegionAndId, Iterable<? extends FloatingIP>> in) {
       return CacheBuilder.newBuilder().build(in);
    }
 
    @Provides
    @Singleton
-   protected LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap(
-            CacheLoader<ZoneAndName, SecurityGroupInZone> in) {
+   protected LoadingCache<RegionAndName, SecurityGroupInRegion> securityGroupMap(
+            CacheLoader<RegionAndName, SecurityGroupInRegion> in) {
       return CacheBuilder.newBuilder().build(in);
    }
    
@@ -195,7 +195,7 @@ public class NovaComputeServiceContextModule extends
    @Provides
    @Singleton
    @Named("SECURITYGROUP_PRESENT")
-   protected Predicate<AtomicReference<ZoneAndName>> securityGroupEventualConsistencyDelay(
+   protected Predicate<AtomicReference<RegionAndName>> securityGroupEventualConsistencyDelay(
             FindSecurityGroupWithNameAndReturnTrue in,
             @Named(TIMEOUT_SECURITYGROUP_PRESENT) long msDelay) {
       return retry(in, msDelay, 100l, MILLISECONDS);
@@ -203,8 +203,8 @@ public class NovaComputeServiceContextModule extends
 
    @Provides
    @Singleton
-   protected LoadingCache<ZoneAndName, KeyPair> keyPairMap(
-         CacheLoader<ZoneAndName, KeyPair> in) {
+   protected LoadingCache<RegionAndName, KeyPair> keyPairMap(
+         CacheLoader<RegionAndName, KeyPair> in) {
       return CacheBuilder.newBuilder().build(in);
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java
index dfee4d1..9e12d97 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaImageExtension.java
@@ -46,7 +46,7 @@ import org.jclouds.domain.Location;
 import org.jclouds.logging.Logger;
 import org.jclouds.openstack.nova.v2_0.NovaApi;
 import org.jclouds.openstack.nova.v2_0.domain.Server;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndId;
 
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
@@ -82,10 +82,10 @@ public class NovaImageExtension implements ImageExtension {
 
    @Override
    public ImageTemplate buildImageTemplateFromNode(String name, final String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
-      Server server = novaApi.getServerApiForZone(zoneAndId.getZone()).get(zoneAndId.getId());
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
+      Server server = novaApi.getServerApi(regionAndId.getRegion()).get(regionAndId.getId());
       if (server == null)
-         throw new NoSuchElementException("Cannot find server with id: " + zoneAndId);
+         throw new NoSuchElementException("Cannot find server with id: " + regionAndId);
       CloneImageTemplate template = new ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name).build();
       return template;
    }
@@ -95,19 +95,19 @@ public class NovaImageExtension implements ImageExtension {
       checkState(template instanceof CloneImageTemplate,
                " openstack-nova only supports creating images through cloning.");
       CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
-      ZoneAndId sourceImageZoneAndId = ZoneAndId.fromSlashEncoded(cloneTemplate.getSourceNodeId());
+      RegionAndId sourceImageRegionAndId = RegionAndId.fromSlashEncoded(cloneTemplate.getSourceNodeId());
 
-      String newImageId = novaApi.getServerApiForZone(sourceImageZoneAndId.getZone()).createImageFromServer(
-               cloneTemplate.getName(), sourceImageZoneAndId.getId());
+      String newImageId = novaApi.getServerApi(sourceImageRegionAndId.getRegion()).createImageFromServer(
+               cloneTemplate.getName(), sourceImageRegionAndId.getId());
 
-      final ZoneAndId targetImageZoneAndId = ZoneAndId.fromZoneAndId(sourceImageZoneAndId.getZone(), newImageId);
+      final RegionAndId targetImageRegionAndId = RegionAndId.fromRegionAndId(sourceImageRegionAndId.getRegion(), newImageId);
 
       logger.info(">> Registered new Image %s, waiting for it to become available.", newImageId);
-      
+
       final AtomicReference<Image> image = Atomics.newReference(new ImageBuilder()
-            .location(find(locations.get(), idEquals(targetImageZoneAndId.getZone())))
-            .id(targetImageZoneAndId.slashEncode())
-            .providerId(targetImageZoneAndId.getId())
+            .location(find(locations.get(), idEquals(targetImageRegionAndId.getRegion())))
+            .id(targetImageRegionAndId.slashEncode())
+            .providerId(targetImageRegionAndId.getId())
             .description(cloneTemplate.getName())
             .operatingSystem(OperatingSystem.builder().description(cloneTemplate.getName()).build())
             .status(Image.Status.PENDING).build());
@@ -125,9 +125,9 @@ public class NovaImageExtension implements ImageExtension {
 
    @Override
    public boolean deleteImage(String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
       try {
-         this.novaApi.getImageApiForZone(zoneAndId.getZone()).delete(zoneAndId.getId());
+         this.novaApi.getImageApi(regionAndId.getRegion()).delete(regionAndId.getId());
       } catch (Exception e) {
          return false;
       }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
index e808ed3..0899bb3 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/extensions/NovaSecurityGroupExtension.java
@@ -40,17 +40,17 @@ import org.jclouds.compute.domain.SecurityGroup;
 import org.jclouds.compute.extensions.SecurityGroupExtension;
 import org.jclouds.compute.functions.GroupNamingConvention;
 import org.jclouds.domain.Location;
-import org.jclouds.location.Zone;
+import org.jclouds.location.Region;
 import org.jclouds.net.domain.IpPermission;
 import org.jclouds.net.domain.IpProtocol;
 import org.jclouds.openstack.nova.v2_0.NovaApi;
 import org.jclouds.openstack.nova.v2_0.domain.Ingress;
 import org.jclouds.openstack.nova.v2_0.domain.SecurityGroupRule;
 import org.jclouds.openstack.nova.v2_0.domain.ServerWithSecurityGroups;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.SecurityGroupInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndName;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndId;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndName;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
 import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
 import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsApi;
 
@@ -70,22 +70,22 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
 
    protected final NovaApi api;
    protected final ListeningExecutorService userExecutor;
-   protected final Supplier<Set<String>> zoneIds;
-   protected final Function<SecurityGroupInZone, SecurityGroup> groupConverter;
-   protected final LoadingCache<ZoneAndName, SecurityGroupInZone> groupCreator;
+   protected final Supplier<Set<String>> regionIds;
+   protected final Function<SecurityGroupInRegion, SecurityGroup> groupConverter;
+   protected final LoadingCache<RegionAndName, SecurityGroupInRegion> groupCreator;
    protected final GroupNamingConvention.Factory namingConvention;
 
    @Inject
    public NovaSecurityGroupExtension(NovaApi api,
                                     @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
-                                    @Zone Supplier<Set<String>> zoneIds,
-                                    Function<SecurityGroupInZone, SecurityGroup> groupConverter,
-                                    LoadingCache<ZoneAndName, SecurityGroupInZone> groupCreator,
+                                    @Region Supplier<Set<String>> regionIds,
+                                    Function<SecurityGroupInRegion, SecurityGroup> groupConverter,
+                                    LoadingCache<RegionAndName, SecurityGroupInRegion> groupCreator,
                                     GroupNamingConvention.Factory namingConvention) {
 
       this.api = checkNotNull(api, "api");
       this.userExecutor = checkNotNull(userExecutor, "userExecutor");
-      this.zoneIds = checkNotNull(zoneIds, "zoneIds");
+      this.regionIds = checkNotNull(regionIds, "regionIds");
       this.groupConverter = checkNotNull(groupConverter, "groupConverter");
       this.groupCreator = checkNotNull(groupCreator, "groupCreator");
       this.namingConvention = checkNotNull(namingConvention, "namingConvention");
@@ -93,7 +93,7 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
 
    @Override
    public Set<SecurityGroup> listSecurityGroups() {
-      Iterable<? extends SecurityGroupInZone> rawGroups = pollSecurityGroups();
+      Iterable<? extends SecurityGroupInRegion> rawGroups = pollSecurityGroups();
       Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
               groupConverter);
       return ImmutableSet.copyOf(groups);
@@ -102,15 +102,15 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
 
    @Override
    public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
-      String zone = location.getId();
-      if (zone == null) {
+      String region = location.getId();
+      if (region == null) {
          return ImmutableSet.of();
       }
-      return listSecurityGroupsInLocation(zone);
+      return listSecurityGroupsInLocation(region);
    }
 
-   public Set<SecurityGroup> listSecurityGroupsInLocation(String zone) {
-      Iterable<? extends SecurityGroupInZone> rawGroups = pollSecurityGroupsByZone(zone);
+   public Set<SecurityGroup> listSecurityGroupsInLocation(String region) {
+      Iterable<? extends SecurityGroupInRegion> rawGroups = pollSecurityGroupsByRegion(region);
       Iterable<SecurityGroup> groups = transform(filter(rawGroups, notNull()),
               groupConverter);
       return ImmutableSet.copyOf(groups);
@@ -118,12 +118,12 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
 
    @Override
    public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(checkNotNull(id, "id"));
-      String zone = zoneAndId.getZone();
-      String instanceId = zoneAndId.getId();
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(checkNotNull(id, "id"));
+      String region = regionAndId.getRegion();
+      String instanceId = regionAndId.getId();
 
-      Optional<? extends ServerWithSecurityGroupsApi> serverApi = api.getServerWithSecurityGroupsExtensionForZone(zone);
-      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+      Optional<? extends ServerWithSecurityGroupsApi> serverApi = api.getServerWithSecurityGroupsApi(region);
+      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupApi(region);
 
       if (!serverApi.isPresent() || !sgApi.isPresent()) {
          return ImmutableSet.of();
@@ -135,54 +135,54 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
       }
 
       Set<String> groupNames = instance.getSecurityGroupNames();
-      Set<? extends SecurityGroupInZone> rawGroups =
-              sgApi.get().list().filter(nameIn(groupNames)).transform(groupToGroupInZone(zone)).toSet();
+      Set<? extends SecurityGroupInRegion> rawGroups =
+              sgApi.get().list().filter(nameIn(groupNames)).transform(groupToGroupInRegion(region)).toSet();
 
       return ImmutableSet.copyOf(transform(filter(rawGroups, notNull()), groupConverter));
    }
 
    @Override
    public SecurityGroup getSecurityGroupById(String id) {
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(checkNotNull(id, "id"));
-      String zone = zoneAndId.getZone();
-      String groupId = zoneAndId.getId();
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(checkNotNull(id, "id"));
+      String region = regionAndId.getRegion();
+      String groupId = regionAndId.getId();
 
-      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupApi(region);
 
       if (!sgApi.isPresent()) {
          return null;
       }
 
-      SecurityGroupInZone rawGroup = new SecurityGroupInZone(sgApi.get().get(groupId), zone);
+      SecurityGroupInRegion rawGroup = new SecurityGroupInRegion(sgApi.get().get(groupId), region);
 
       return groupConverter.apply(rawGroup);
    }
 
    @Override
    public SecurityGroup createSecurityGroup(String name, Location location) {
-      String zone = location.getId();
-      if (zone == null) {
+      String region = location.getId();
+      if (region == null) {
          return null;
       }
-      return createSecurityGroup(name, zone);
+      return createSecurityGroup(name, region);
    }
 
-   public SecurityGroup createSecurityGroup(String name, String zone) {
+   public SecurityGroup createSecurityGroup(String name, String region) {
       String markerGroup = namingConvention.create().sharedNameForGroup(name);
-      ZoneSecurityGroupNameAndPorts zoneAndName = new ZoneSecurityGroupNameAndPorts(zone, markerGroup, ImmutableSet.<Integer> of());
+      RegionSecurityGroupNameAndPorts regionAndName = new RegionSecurityGroupNameAndPorts(region, markerGroup, ImmutableSet.<Integer> of());
 
-      SecurityGroupInZone rawGroup = groupCreator.getUnchecked(zoneAndName);
+      SecurityGroupInRegion rawGroup = groupCreator.getUnchecked(regionAndName);
       return groupConverter.apply(rawGroup);
    }
 
    @Override
    public boolean removeSecurityGroup(String id) {
       checkNotNull(id, "id");
-      ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id);
-      String zone = zoneAndId.getZone();
-      String groupId = zoneAndId.getId();
+      RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
+      String region = regionAndId.getRegion();
+      String groupId = regionAndId.getId();
 
-      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupApi(region);
 
       if (!sgApi.isPresent()) {
          return false;
@@ -194,16 +194,16 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
 
       sgApi.get().delete(groupId);
       // TODO: test this clear happens
-      groupCreator.invalidate(new ZoneSecurityGroupNameAndPorts(zone, groupId, ImmutableSet.<Integer> of()));
+      groupCreator.invalidate(new RegionSecurityGroupNameAndPorts(region, groupId, ImmutableSet.<Integer> of()));
       return true;
    }
 
    @Override
    public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
-      String zone = group.getLocation().getId();
-      ZoneAndId groupZoneAndId = ZoneAndId.fromSlashEncoded(group.getId());
-      String id = groupZoneAndId.getId();
-      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+      String region = group.getLocation().getId();
+      RegionAndId groupRegionAndId = RegionAndId.fromSlashEncoded(group.getId());
+      String id = groupRegionAndId.getId();
+      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupApi(region);
 
       if (!sgApi.isPresent()) {
          return null;
@@ -222,9 +222,9 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
       }
 
       if (ipPermission.getGroupIds().size() > 0) {
-         for (String zoneAndGroupRaw : ipPermission.getGroupIds()) {
-            ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(zoneAndGroupRaw);
-            String groupId = zoneAndId.getId();
+         for (String regionAndGroupRaw : ipPermission.getGroupIds()) {
+            RegionAndId regionAndId = RegionAndId.fromSlashEncoded(regionAndGroupRaw);
+            String groupId = regionAndId.getId();
             sgApi.get().createRuleAllowingSecurityGroupId(id,
                     Ingress.builder()
                             .ipProtocol(ipPermission.getIpProtocol())
@@ -235,7 +235,7 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
          }
       }
 
-      return getSecurityGroupById(ZoneAndId.fromZoneAndId(zone, id).slashEncode());
+      return getSecurityGroupById(RegionAndId.fromRegionAndId(region, id).slashEncode());
    }
 
    @Override
@@ -256,11 +256,11 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
 
    @Override
    public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
-      String zone = group.getLocation().getId();
-      ZoneAndId groupZoneAndId = ZoneAndId.fromSlashEncoded(group.getId());
-      String id = groupZoneAndId.getId();
+      String region = group.getLocation().getId();
+      RegionAndId groupRegionAndId = RegionAndId.fromSlashEncoded(group.getId());
+      String id = groupRegionAndId.getId();
 
-      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(zone);
+      Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupApi(region);
 
       if (!sgApi.isPresent()) {
          return null;
@@ -291,7 +291,7 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
          }
       }
 
-      return getSecurityGroupById(ZoneAndId.fromZoneAndId(zone, id).slashEncode());
+      return getSecurityGroupById(RegionAndId.fromRegionAndId(region, id).slashEncode());
    }
 
    @Override
@@ -330,41 +330,41 @@ public class NovaSecurityGroupExtension implements SecurityGroupExtension {
       return false;
    }
 
-   protected Iterable<? extends SecurityGroupInZone> pollSecurityGroups() {
-      Iterable<? extends Set<? extends SecurityGroupInZone>> groups
-              = transform(zoneIds.get(), allSecurityGroupsInZone());
+   protected Iterable<? extends SecurityGroupInRegion> pollSecurityGroups() {
+      Iterable<? extends Set<? extends SecurityGroupInRegion>> groups
+              = transform(regionIds.get(), allSecurityGroupsInRegion());
 
       return concat(groups);
    }
 
 
-   protected Iterable<? extends SecurityGroupInZone> pollSecurityGroupsByZone(String zone) {
-      return allSecurityGroupsInZone().apply(zone);
+   protected Iterable<? extends SecurityGroupInRegion> pollSecurityGroupsByRegion(String region) {
+      return allSecurityGroupsInRegion().apply(region);
    }
 
-   protected Function<String, Set<? extends SecurityGroupInZone>> allSecurityGroupsInZone() {
-      return new Function<String, Set<? extends SecurityGroupInZone>>() {
+   protected Function<String, Set<? extends SecurityGroupInRegion>> allSecurityGroupsInRegion() {
+      return new Function<String, Set<? extends SecurityGroupInRegion>>() {
 
          @Override
-         public Set<? extends SecurityGroupInZone> apply(final String from) {
-            Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupExtensionForZone(from);
+         public Set<? extends SecurityGroupInRegion> apply(final String from) {
+            Optional<? extends SecurityGroupApi> sgApi = api.getSecurityGroupApi(from);
 
             if (!sgApi.isPresent()) {
                return ImmutableSet.of();
             }
 
 
-            return sgApi.get().list().transform(groupToGroupInZone(from)).toSet();
+            return sgApi.get().list().transform(groupToGroupInRegion(from)).toSet();
          }
 
       };
    }
 
-   protected Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroupInZone> groupToGroupInZone(final String zone) {
-      return new Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroupInZone>() {
+   protected Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroupInRegion> groupToGroupInRegion(final String region) {
+      return new Function<org.jclouds.openstack.nova.v2_0.domain.SecurityGroup, SecurityGroupInRegion>() {
          @Override
-         public SecurityGroupInZone apply(org.jclouds.openstack.nova.v2_0.domain.SecurityGroup group) {
-            return new SecurityGroupInZone(group, zone);
+         public SecurityGroupInRegion apply(org.jclouds.openstack.nova.v2_0.domain.SecurityGroup group) {
+            return new SecurityGroupInRegion(group, region);
          }
       };
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
index b734e07..1de8fd8 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/AllocateAndAddFloatingIpToNode.java
@@ -35,7 +35,7 @@ import org.jclouds.logging.Logger;
 import org.jclouds.openstack.nova.v2_0.NovaApi;
 import org.jclouds.openstack.nova.v2_0.compute.options.NodeAndNovaTemplateOptions;
 import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneAndId;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionAndId;
 import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
 import org.jclouds.rest.InsufficientResourcesException;
 
@@ -60,11 +60,11 @@ public class AllocateAndAddFloatingIpToNode implements
 
    private final Predicate<AtomicReference<NodeMetadata>> nodeRunning;
    private final NovaApi novaApi;
-   private final LoadingCache<ZoneAndId, Iterable<? extends FloatingIP>> floatingIpCache;
+   private final LoadingCache<RegionAndId, Iterable<? extends FloatingIP>> floatingIpCache;
 
    @Inject
    public AllocateAndAddFloatingIpToNode(@Named(TIMEOUT_NODE_RUNNING) Predicate<AtomicReference<NodeMetadata>> nodeRunning,
-            NovaApi novaApi, @Named("FLOATINGIP") LoadingCache<ZoneAndId, Iterable<? extends FloatingIP>> floatingIpCache) {
+            NovaApi novaApi, @Named("FLOATINGIP") LoadingCache<RegionAndId, Iterable<? extends FloatingIP>> floatingIpCache) {
       this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
       this.novaApi = checkNotNull(novaApi, "novaApi");
       this.floatingIpCache = checkNotNull(floatingIpCache, "floatingIpCache");
@@ -75,8 +75,8 @@ public class AllocateAndAddFloatingIpToNode implements
       checkState(nodeRunning.apply(input.get().getNodeMetadata()), "node never achieved state running %s", input.get().getNodeMetadata());
       NodeMetadata node = input.get().getNodeMetadata().get();
       // node's location is a host
-      String zoneId = node.getLocation().getParent().getId();
-      FloatingIPApi floatingIpApi = novaApi.getFloatingIPExtensionForZone(zoneId).get();
+      String regionId = node.getLocation().getParent().getId();
+      FloatingIPApi floatingIpApi = novaApi.getFloatingIPApi(regionId).get();
       Optional<Set<String>> poolNames = input.get().getNovaTemplateOptions().get().getFloatingIpPoolNames();
 
       Optional<FloatingIP> ip = allocateFloatingIPForNode(floatingIpApi, poolNames, node.getId());
@@ -87,7 +87,7 @@ public class AllocateAndAddFloatingIpToNode implements
 
       floatingIpApi.addToServer(ip.get().getIp(), node.getProviderId());
       input.get().getNodeMetadata().set(NodeMetadataBuilder.fromNodeMetadata(node).publicAddresses(ImmutableSet.of(ip.get().getIp())).build());
-      floatingIpCache.invalidate(ZoneAndId.fromSlashEncoded(node.getId()));
+      floatingIpCache.invalidate(RegionAndId.fromSlashEncoded(node.getId()));
       return input.get().getNodeMetadata();
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
index 5a87105..4c2c8cc 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/CreateSecurityGroupIfNeeded.java
@@ -32,15 +32,15 @@ import org.jclouds.net.domain.IpProtocol;
 import org.jclouds.openstack.nova.v2_0.NovaApi;
 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.zonescoped.SecurityGroupInZone;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.SecurityGroupInRegion;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.RegionSecurityGroupNameAndPorts;
 import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
 
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
 
 @Singleton
-public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> {
+public class CreateSecurityGroupIfNeeded implements Function<RegionSecurityGroupNameAndPorts, SecurityGroupInRegion> {
    @Resource
    @Named(ComputeServiceConstants.COMPUTE_LOGGER)
    protected Logger logger = Logger.NULL;
@@ -52,29 +52,29 @@ public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNa
    }
 
    @Override
-   public SecurityGroupInZone apply(ZoneSecurityGroupNameAndPorts zoneSecurityGroupNameAndPorts) {
-      checkNotNull(zoneSecurityGroupNameAndPorts, "zoneSecurityGroupNameAndPorts");
+   public SecurityGroupInRegion apply(RegionSecurityGroupNameAndPorts regionSecurityGroupNameAndPorts) {
+      checkNotNull(regionSecurityGroupNameAndPorts, "regionSecurityGroupNameAndPorts");
 
-      String zoneId = zoneSecurityGroupNameAndPorts.getZone();
-      Optional<? extends SecurityGroupApi> api = novaApi.getSecurityGroupExtensionForZone(zoneId);
-      checkArgument(api.isPresent(), "Security groups are required, but the extension is not availablein zone %s!", zoneId);
-      logger.debug(">> creating securityGroup %s", zoneSecurityGroupNameAndPorts);
+      String regionId = regionSecurityGroupNameAndPorts.getRegion();
+      Optional<? extends SecurityGroupApi> api = novaApi.getSecurityGroupApi(regionId);
+      checkArgument(api.isPresent(), "Security groups are required, but the extension is not available in region %s!", regionId);
+      logger.debug(">> creating securityGroup %s", regionSecurityGroupNameAndPorts);
       try {
 
          SecurityGroup securityGroup = api.get().createWithDescription(
-                  zoneSecurityGroupNameAndPorts.getName(), zoneSecurityGroupNameAndPorts.getName());
+                  regionSecurityGroupNameAndPorts.getName(), regionSecurityGroupNameAndPorts.getName());
 
          logger.debug("<< created securityGroup(%s)", securityGroup);
-         for (int port : zoneSecurityGroupNameAndPorts.getPorts()) {
+         for (int port : regionSecurityGroupNameAndPorts.getPorts()) {
             authorizeGroupToItselfAndAllIPsToTCPPort(api.get(), securityGroup, port);
          }
-         return new SecurityGroupInZone(api.get().get(securityGroup.getId()), zoneId);
+         return new SecurityGroupInRegion(api.get().get(securityGroup.getId()), regionId);
       } catch (IllegalStateException e) {
-         logger.trace("<< trying to find securityGroup(%s): %s", zoneSecurityGroupNameAndPorts, e.getMessage());
-         SecurityGroup group = find(api.get().list(), nameEquals(zoneSecurityGroupNameAndPorts
+         logger.trace("<< trying to find securityGroup(%s): %s", regionSecurityGroupNameAndPorts, e.getMessage());
+         SecurityGroup group = find(api.get().list(), nameEquals(regionSecurityGroupNameAndPorts
                   .getName()));
          logger.debug("<< reused securityGroup(%s)", group.getId());
-         return new SecurityGroupInZone(group, zoneId);
+         return new SecurityGroupInRegion(group, regionId);
       }
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInRegionToHardware.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInRegionToHardware.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInRegionToHardware.java
new file mode 100644
index 0000000..7387bed
--- /dev/null
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInRegionToHardware.java
@@ -0,0 +1,58 @@
+/*
+ * 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.compute.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.internal.VolumeImpl;
+import org.jclouds.domain.Location;
+import org.jclouds.openstack.nova.v2_0.domain.Flavor;
+import org.jclouds.openstack.nova.v2_0.domain.regionscoped.FlavorInRegion;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+
+/**
+ * A function for transforming the nova specific FlavorInRegion object to the generic Hardware object.
+ */
+public class FlavorInRegionToHardware implements Function<FlavorInRegion, Hardware> {
+
+   private final Supplier<Map<String, Location>> locationIndex;
+
+   @Inject
+   public FlavorInRegionToHardware(Supplier<Map<String, Location>> locationIndex) {
+      this.locationIndex = checkNotNull(locationIndex, "locationIndex");
+   }
+
+   @Override
+   public Hardware apply(FlavorInRegion flavorInRegion) {
+      Location location = locationIndex.get().get(flavorInRegion.getRegion());
+      checkState(location != null, "location %s not in locationIndex: %s", flavorInRegion.getRegion(), locationIndex.get());
+      Flavor flavor = flavorInRegion.getFlavor();
+      return new HardwareBuilder().id(flavorInRegion.slashEncode()).providerId(flavor.getId()).name(flavor.getName())
+               .ram(flavor.getRam()).processor(new Processor(flavor.getVcpus(), 1.0)).volume(
+                        new VolumeImpl(Float.valueOf(flavor.getDisk()), true, true)).location(location).build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/744cd5d7/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInZoneToHardware.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInZoneToHardware.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInZoneToHardware.java
deleted file mode 100644
index 4e8a776..0000000
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/compute/functions/FlavorInZoneToHardware.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.compute.functions;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.jclouds.compute.domain.Hardware;
-import org.jclouds.compute.domain.HardwareBuilder;
-import org.jclouds.compute.domain.Processor;
-import org.jclouds.compute.domain.internal.VolumeImpl;
-import org.jclouds.domain.Location;
-import org.jclouds.openstack.nova.v2_0.domain.Flavor;
-import org.jclouds.openstack.nova.v2_0.domain.zonescoped.FlavorInZone;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-
-/**
- * A function for transforming the nova specific FlavorInZone object to the generic Hardware object.
- */
-public class FlavorInZoneToHardware implements Function<FlavorInZone, Hardware> {
-
-   private final Supplier<Map<String, Location>> locationIndex;
-
-   @Inject
-   public FlavorInZoneToHardware(Supplier<Map<String, Location>> locationIndex) {
-      this.locationIndex = checkNotNull(locationIndex, "locationIndex");
-   }
-
-   @Override
-   public Hardware apply(FlavorInZone flavorInZone) {
-      Location location = locationIndex.get().get(flavorInZone.getZone());
-      checkState(location != null, "location %s not in locationIndex: %s", flavorInZone.getZone(), locationIndex.get());
-      Flavor flavor = flavorInZone.getFlavor();
-      return new HardwareBuilder().id(flavorInZone.slashEncode()).providerId(flavor.getId()).name(flavor.getName())
-               .ram(flavor.getRam()).processor(new Processor(flavor.getVcpus(), 1.0)).volume(
-                        new VolumeImpl(Float.valueOf(flavor.getDisk()), true, true)).location(location).build();
-   }
-}