You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2017/12/08 12:56:16 UTC

[1/8] jclouds git commit: Initial work towards Keystone V3 authentication

Repository: jclouds
Updated Branches:
  refs/heads/keystonev3 [created] 17c11ec9d


http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/domain/ApiKeyCredentials.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/domain/ApiKeyCredentials.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/domain/ApiKeyCredentials.java
index 4976ec2..c8f74af 100644
--- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/domain/ApiKeyCredentials.java
+++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/domain/ApiKeyCredentials.java
@@ -16,11 +16,11 @@
  */
 package org.jclouds.rackspace.cloudidentity.v2_0.domain;
 
-import static com.google.common.base.Objects.equal;
 import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Objects.equal;
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
+import org.jclouds.openstack.keystone.auth.config.CredentialType;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 
 import com.google.common.base.Objects;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/functions/AuthenticateApiKeyCredentials.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/functions/AuthenticateApiKeyCredentials.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/functions/AuthenticateApiKeyCredentials.java
index b4070bb..5e54244 100644
--- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/functions/AuthenticateApiKeyCredentials.java
+++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/functions/AuthenticateApiKeyCredentials.java
@@ -19,15 +19,14 @@ package org.jclouds.rackspace.cloudidentity.v2_0.functions;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
-import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.functions.internal.BaseAuthenticator;
+import org.jclouds.openstack.keystone.auth.config.CredentialType;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+import org.jclouds.openstack.keystone.auth.functions.BaseAuthenticator;
 import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityAuthenticationApi;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 import org.jclouds.rackspace.cloudidentity.v2_0.domain.ApiKeyCredentials;
 
-import com.google.common.base.Optional;
-
 /**
  * 
  * @see <a
@@ -39,21 +38,11 @@ public class AuthenticateApiKeyCredentials extends BaseAuthenticator<ApiKeyCrede
    protected final CloudIdentityAuthenticationApi api;
 
    @Inject
-   public AuthenticateApiKeyCredentials(CloudIdentityAuthenticationApi api) {
+   AuthenticateApiKeyCredentials(CloudIdentityAuthenticationApi api) {
       this.api = api;
    }
 
    @Override
-   protected Access authenticateWithTenantName(Optional<String> tenantId, ApiKeyCredentials apiKeyCredentials) {
-      return api.authenticateWithTenantNameAndCredentials(tenantId.orNull(), apiKeyCredentials);
-   }
-
-   @Override
-   protected Access authenticateWithTenantId(Optional<String> tenantId, ApiKeyCredentials apiKeyCredentials) {
-      return api.authenticateWithTenantIdAndCredentials(tenantId.orNull(), apiKeyCredentials);
-   }
-
-   @Override
    public ApiKeyCredentials createCredentials(String identity, String credential) {
       return ApiKeyCredentials.createWithUsernameAndApiKey(identity, credential);
    }
@@ -62,4 +51,9 @@ public class AuthenticateApiKeyCredentials extends BaseAuthenticator<ApiKeyCrede
    public String toString() {
       return "authenticateApiKeyCredentials()";
    }
+
+   @Override
+   public AuthInfo authenticate(TenantAndCredentials<ApiKeyCredentials> credentials) {
+      return api.authenticateApiKey(credentials);
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApiMetadata.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApiMetadata.java
index 67e0795..0c92fa2 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApiMetadata.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/CloudLoadBalancersApiMetadata.java
@@ -16,8 +16,9 @@
  */
 package org.jclouds.rackspace.cloudloadbalancers.v1;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 import static org.jclouds.reflect.Reflection2.typeToken;
 
 import java.net.URI;
@@ -25,9 +26,9 @@ import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
 import org.jclouds.loadbalancer.LoadBalancerServiceContext;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.ServiceType;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 import org.jclouds.rackspace.cloudloadbalancers.v1.config.CloudLoadBalancersHttpApiModule;
@@ -61,6 +62,7 @@ public class CloudLoadBalancersApiMetadata extends BaseHttpApiMetadata<CloudLoad
       Properties properties = BaseHttpApiMetadata.defaultProperties();
       properties.setProperty(SERVICE_TYPE, ServiceType.LOAD_BALANCERS);
       properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       return properties;
    }
 
@@ -77,8 +79,8 @@ public class CloudLoadBalancersApiMetadata extends BaseHttpApiMetadata<CloudLoad
                .defaultProperties(CloudLoadBalancersApiMetadata.defaultProperties())
                .view(typeToken(LoadBalancerServiceContext.class))
                .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                            .add(CloudIdentityAuthenticationApiModule.class)
                             .add(CloudIdentityAuthenticationModule.class)
+                            .add(ServiceCatalogModule.class)
                             .add(RegionModule.class)
                             .add(CloudLoadBalancersHttpApiModule.class)
                             .add(CloudLoadBalancersLoadBalancerContextModule.class).build());

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleApi.java
index 2617b22..f862cf1 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/AccessRuleApi.java
@@ -29,7 +29,7 @@ import javax.ws.rs.core.MediaType;
 import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AccessRule;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AccessRuleWithId;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionApi.java
index 8901e9e..318f56c 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ConnectionApi.java
@@ -29,7 +29,7 @@ import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.Fallbacks.FalseOnNotFoundOr422;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.ConnectionThrottle;
 import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNestedBoolean;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingApi.java
index 3c092f4..ad623f2 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ContentCachingApi.java
@@ -26,7 +26,7 @@ import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNestedBoolean;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.Payload;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageApi.java
index 07b3786..bcc749b 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ErrorPageApi.java
@@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseNestedString;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.Payload;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorApi.java
index 4d6fc95..5c4e095 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/HealthMonitorApi.java
@@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType;
 import org.jclouds.Fallbacks.FalseOnNotFoundOr422;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.HealthMonitor;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerApi.java
index 8945d68..3732813 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/LoadBalancerApi.java
@@ -37,8 +37,8 @@ import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.collect.IterableWithMarker;
 import org.jclouds.collect.PagedIterable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.options.PaginationOptions;
 import org.jclouds.rackspace.cloudloadbalancers.v1.binders.BindMetadataToJsonPayload;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.CreateLoadBalancer;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeApi.java
index b64b363..ceedc48 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/NodeApi.java
@@ -38,8 +38,8 @@ import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.collect.IterableWithMarker;
 import org.jclouds.collect.PagedIterable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.options.PaginationOptions;
 import org.jclouds.rackspace.cloudloadbalancers.v1.binders.BindMetadataToJsonPayload;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.AddNode;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportApi.java
index 9508f12..b3c363d 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/ReportApi.java
@@ -29,8 +29,8 @@ import javax.ws.rs.core.MediaType;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.collect.IterableWithMarker;
 import org.jclouds.collect.PagedIterable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.options.PaginationOptions;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.HistoricalUsage;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.LoadBalancer;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationApi.java
index 96f0a25..cd7c1ff 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SSLTerminationApi.java
@@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType;
 import org.jclouds.Fallbacks.FalseOnNotFoundOr422;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.SSLTermination;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceApi.java
index 1a57d62..350bf20 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/SessionPersistenceApi.java
@@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.SessionPersistence;
 import org.jclouds.rackspace.cloudloadbalancers.v1.functions.ParseSessionPersistence;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPApi.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPApi.java
index 42b9135..a85505d 100644
--- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPApi.java
+++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/v1/features/VirtualIPApi.java
@@ -29,7 +29,7 @@ import javax.ws.rs.core.MediaType;
 import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.VirtualIP;
 import org.jclouds.rackspace.cloudloadbalancers.v1.domain.VirtualIPWithId;
 import org.jclouds.rest.annotations.BinderParam;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/v1/internal/BaseCloudLoadBalancersApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/v1/internal/BaseCloudLoadBalancersApiLiveTest.java b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/v1/internal/BaseCloudLoadBalancersApiLiveTest.java
index b4d69f3..5bb2027 100644
--- a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/v1/internal/BaseCloudLoadBalancersApiLiveTest.java
+++ b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/v1/internal/BaseCloudLoadBalancersApiLiveTest.java
@@ -20,7 +20,7 @@ import java.util.Properties;
 import java.util.logging.Logger;
 
 import org.jclouds.apis.BaseApiLiveTest;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.rackspace.cloudloadbalancers.v1.CloudLoadBalancersApi;
 import org.testng.annotations.BeforeGroups;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/providers/rackspace-cloudblockstorage-uk/src/main/java/org/jclouds/rackspace/cloudblockstorage/uk/CloudBlockStorageUKProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/rackspace-cloudblockstorage-uk/src/main/java/org/jclouds/rackspace/cloudblockstorage/uk/CloudBlockStorageUKProviderMetadata.java b/providers/rackspace-cloudblockstorage-uk/src/main/java/org/jclouds/rackspace/cloudblockstorage/uk/CloudBlockStorageUKProviderMetadata.java
index 51b532f..33b8321 100644
--- a/providers/rackspace-cloudblockstorage-uk/src/main/java/org/jclouds/rackspace/cloudblockstorage/uk/CloudBlockStorageUKProviderMetadata.java
+++ b/providers/rackspace-cloudblockstorage-uk/src/main/java/org/jclouds/rackspace/cloudblockstorage/uk/CloudBlockStorageUKProviderMetadata.java
@@ -19,7 +19,8 @@ package org.jclouds.rackspace.cloudblockstorage.uk;
 import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
 
 import java.net.URI;
 import java.util.Properties;
@@ -27,10 +28,10 @@ import java.util.Properties;
 import org.jclouds.openstack.cinder.v1.CinderApiMetadata;
 import org.jclouds.openstack.cinder.v1.config.CinderHttpApiModule;
 import org.jclouds.openstack.cinder.v1.config.CinderParserModule;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 
@@ -64,6 +65,7 @@ public class CloudBlockStorageUKProviderMetadata extends BaseProviderMetadata {
    public static Properties defaultProperties() {
       Properties properties = new Properties();
       properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       properties.setProperty(PROPERTY_REGIONS, "LON");
       properties.setProperty(PROPERTY_REGION + ".LON." + ISO3166_CODES, "GB-SLG");
       return properties;
@@ -81,8 +83,8 @@ public class CloudBlockStorageUKProviderMetadata extends BaseProviderMetadata {
                   .endpointName("identity service url ending in /v2.0/")
                   .documentation(URI.create("http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/overview.html"))
                   .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                              .add(CloudIdentityAuthenticationApiModule.class)
                                               .add(CloudIdentityAuthenticationModule.class)
+                                              .add(ServiceCatalogModule.class)
                                               .add(RegionModule.class)
                                               .add(CinderParserModule.class)
                                               .add(CinderHttpApiModule.class).build())

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/providers/rackspace-cloudblockstorage-us/src/main/java/org/jclouds/rackspace/cloudblockstorage/us/CloudBlockStorageUSProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/rackspace-cloudblockstorage-us/src/main/java/org/jclouds/rackspace/cloudblockstorage/us/CloudBlockStorageUSProviderMetadata.java b/providers/rackspace-cloudblockstorage-us/src/main/java/org/jclouds/rackspace/cloudblockstorage/us/CloudBlockStorageUSProviderMetadata.java
index 19675fa..761ab04 100644
--- a/providers/rackspace-cloudblockstorage-us/src/main/java/org/jclouds/rackspace/cloudblockstorage/us/CloudBlockStorageUSProviderMetadata.java
+++ b/providers/rackspace-cloudblockstorage-us/src/main/java/org/jclouds/rackspace/cloudblockstorage/us/CloudBlockStorageUSProviderMetadata.java
@@ -19,7 +19,8 @@ package org.jclouds.rackspace.cloudblockstorage.us;
 import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
 
 import java.net.URI;
 import java.util.Properties;
@@ -27,10 +28,10 @@ import java.util.Properties;
 import org.jclouds.openstack.cinder.v1.CinderApiMetadata;
 import org.jclouds.openstack.cinder.v1.config.CinderHttpApiModule;
 import org.jclouds.openstack.cinder.v1.config.CinderParserModule;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 
@@ -64,6 +65,7 @@ public class CloudBlockStorageUSProviderMetadata extends BaseProviderMetadata {
    public static Properties defaultProperties() {
       Properties properties = new Properties();
       properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       properties.setProperty(PROPERTY_REGIONS, "ORD,DFW,IAD,SYD,HKG");
       properties.setProperty(PROPERTY_REGION + ".ORD." + ISO3166_CODES, "US-IL");
       properties.setProperty(PROPERTY_REGION + ".DFW." + ISO3166_CODES, "US-TX");
@@ -85,8 +87,8 @@ public class CloudBlockStorageUSProviderMetadata extends BaseProviderMetadata {
                   .endpointName("identity service url ending in /v2.0/")
                   .documentation(URI.create("http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/overview.html"))
                   .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                              .add(CloudIdentityAuthenticationApiModule.class)
                                               .add(CloudIdentityAuthenticationModule.class)
+                                              .add(ServiceCatalogModule.class)
                                               .add(RegionModule.class)
                                               .add(CinderParserModule.class)
                                               .add(CinderHttpApiModule.class).build())

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/providers/rackspace-clouddatabases-uk/src/main/java/org/jclouds/rackspace/clouddatabases/uk/CloudDatabasesUKProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/rackspace-clouddatabases-uk/src/main/java/org/jclouds/rackspace/clouddatabases/uk/CloudDatabasesUKProviderMetadata.java b/providers/rackspace-clouddatabases-uk/src/main/java/org/jclouds/rackspace/clouddatabases/uk/CloudDatabasesUKProviderMetadata.java
index 307e86f..5291dc2 100644
--- a/providers/rackspace-clouddatabases-uk/src/main/java/org/jclouds/rackspace/clouddatabases/uk/CloudDatabasesUKProviderMetadata.java
+++ b/providers/rackspace-clouddatabases-uk/src/main/java/org/jclouds/rackspace/clouddatabases/uk/CloudDatabasesUKProviderMetadata.java
@@ -19,20 +19,21 @@ package org.jclouds.rackspace.clouddatabases.uk;
 import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 
 import java.net.URI;
 import java.util.Properties;
 
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.trove.v1.TroveApiMetadata;
 import org.jclouds.openstack.trove.v1.config.TroveHttpApiModule;
 import org.jclouds.openstack.trove.v1.config.TroveParserModule;
 import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
 import org.jclouds.rackspace.cloudidentity.v2_0.ServiceType;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 
@@ -67,6 +68,7 @@ public class CloudDatabasesUKProviderMetadata extends BaseProviderMetadata {
       Properties properties = new Properties();
       properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
       properties.setProperty(SERVICE_TYPE, ServiceType.DATABASES);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       properties.setProperty(PROPERTY_REGIONS, "LON");
       properties.setProperty(PROPERTY_REGION + ".LON." + ISO3166_CODES, "GB-SLG");
       return properties;
@@ -84,8 +86,8 @@ public class CloudDatabasesUKProviderMetadata extends BaseProviderMetadata {
                   .endpointName("identity service url ending in /v2.0/")
                   .documentation(URI.create("http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/overview.html"))
                   .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                              .add(CloudIdentityAuthenticationApiModule.class)
                                               .add(CloudIdentityAuthenticationModule.class)
+                                              .add(ServiceCatalogModule.class)
                                               .add(RegionModule.class)
                                               .add(TroveParserModule.class)
                                               .add(TroveHttpApiModule.class).build())

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/providers/rackspace-clouddatabases-us/src/main/java/org/jclouds/rackspace/clouddatabases/us/CloudDatabasesUSProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/rackspace-clouddatabases-us/src/main/java/org/jclouds/rackspace/clouddatabases/us/CloudDatabasesUSProviderMetadata.java b/providers/rackspace-clouddatabases-us/src/main/java/org/jclouds/rackspace/clouddatabases/us/CloudDatabasesUSProviderMetadata.java
index 4d595a7..ec94a12 100644
--- a/providers/rackspace-clouddatabases-us/src/main/java/org/jclouds/rackspace/clouddatabases/us/CloudDatabasesUSProviderMetadata.java
+++ b/providers/rackspace-clouddatabases-us/src/main/java/org/jclouds/rackspace/clouddatabases/us/CloudDatabasesUSProviderMetadata.java
@@ -19,20 +19,21 @@ package org.jclouds.rackspace.clouddatabases.us;
 import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 
 import java.net.URI;
 import java.util.Properties;
 
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.trove.v1.TroveApiMetadata;
 import org.jclouds.openstack.trove.v1.config.TroveHttpApiModule;
 import org.jclouds.openstack.trove.v1.config.TroveParserModule;
 import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
 import org.jclouds.rackspace.cloudidentity.v2_0.ServiceType;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 
@@ -66,6 +67,7 @@ public class CloudDatabasesUSProviderMetadata extends BaseProviderMetadata {
    public static Properties defaultProperties() {
       Properties properties = new Properties();
       properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       properties.setProperty(SERVICE_TYPE, ServiceType.DATABASES);
       properties.setProperty(PROPERTY_REGIONS, "ORD,DFW,IAD,SYD,HKG");
       properties.setProperty(PROPERTY_REGION + ".ORD." + ISO3166_CODES, "US-IL");
@@ -88,8 +90,8 @@ public class CloudDatabasesUSProviderMetadata extends BaseProviderMetadata {
                   .endpointName("identity service url ending in /v2.0/")
                   .documentation(URI.create("http://docs.rackspace.com/cbs/api/v1.0/cbs-devguide/content/overview.html"))
                   .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                              .add(CloudIdentityAuthenticationApiModule.class)
                                               .add(CloudIdentityAuthenticationModule.class)
+                                              .add(ServiceCatalogModule.class)
                                               .add(RegionModule.class)
                                               .add(TroveParserModule.class)
                                               .add(TroveHttpApiModule.class).build())

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/providers/rackspace-cloudfiles-uk/src/main/java/org/jclouds/rackspace/cloudfiles/uk/CloudFilesUKProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/rackspace-cloudfiles-uk/src/main/java/org/jclouds/rackspace/cloudfiles/uk/CloudFilesUKProviderMetadata.java b/providers/rackspace-cloudfiles-uk/src/main/java/org/jclouds/rackspace/cloudfiles/uk/CloudFilesUKProviderMetadata.java
index bf4eefa..7307f19 100644
--- a/providers/rackspace-cloudfiles-uk/src/main/java/org/jclouds/rackspace/cloudfiles/uk/CloudFilesUKProviderMetadata.java
+++ b/providers/rackspace-cloudfiles-uk/src/main/java/org/jclouds/rackspace/cloudfiles/uk/CloudFilesUKProviderMetadata.java
@@ -19,14 +19,16 @@ package org.jclouds.rackspace.cloudfiles.uk;
 import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 import static org.jclouds.reflect.Reflection2.typeToken;
 
 import java.net.URI;
 import java.util.Properties;
 
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.swift.v1.blobstore.RegionScopedBlobStoreContext;
 import org.jclouds.openstack.swift.v1.blobstore.config.SignUsingTemporaryUrls;
 import org.jclouds.openstack.swift.v1.blobstore.config.SwiftBlobStoreContextModule;
@@ -36,7 +38,6 @@ import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
 import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApiMetadata;
 import org.jclouds.rackspace.cloudfiles.v1.config.CloudFilesHttpApiModule;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 
@@ -68,6 +69,7 @@ public class CloudFilesUKProviderMetadata extends BaseProviderMetadata {
       Properties properties = new Properties();
       properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
       properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE); 
+      properties.setProperty(KEYSTONE_VERSION, "2"); 
 
       properties.setProperty(PROPERTY_REGIONS, "LON");
       properties.setProperty(PROPERTY_REGION + ".LON." + ISO3166_CODES, "GB-SLG");
@@ -89,8 +91,8 @@ public class CloudFilesUKProviderMetadata extends BaseProviderMetadata {
                .version("1.0")
                .view(typeToken(RegionScopedBlobStoreContext.class))
                .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                     .add(CloudIdentityAuthenticationApiModule.class)
                      .add(CloudIdentityAuthenticationModule.class)
+                     .add(ServiceCatalogModule.class)
                      .add(RegionModule.class)
                      .add(SwiftTypeAdapters.class)
                      .add(CloudFilesHttpApiModule.class)

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/providers/rackspace-cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/rackspace-cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderMetadata.java b/providers/rackspace-cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderMetadata.java
index cea0ebd..76c83eb 100644
--- a/providers/rackspace-cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderMetadata.java
+++ b/providers/rackspace-cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/us/CloudFilesUSProviderMetadata.java
@@ -19,14 +19,16 @@ package org.jclouds.rackspace.cloudfiles.us;
 import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 import static org.jclouds.reflect.Reflection2.typeToken;
 
 import java.net.URI;
 import java.util.Properties;
 
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.swift.v1.blobstore.RegionScopedBlobStoreContext;
 import org.jclouds.openstack.swift.v1.blobstore.config.SignUsingTemporaryUrls;
 import org.jclouds.openstack.swift.v1.blobstore.config.SwiftBlobStoreContextModule;
@@ -36,7 +38,6 @@ import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
 import org.jclouds.rackspace.cloudfiles.v1.CloudFilesApiMetadata;
 import org.jclouds.rackspace.cloudfiles.v1.config.CloudFilesHttpApiModule;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 
@@ -82,7 +83,8 @@ public class CloudFilesUSProviderMetadata extends BaseProviderMetadata {
    public static Properties defaultProperties() {
       Properties properties = new Properties();
       properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
-      properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE); 
+      properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE);
+      properties.setProperty(KEYSTONE_VERSION, "2");
 
       properties.setProperty(PROPERTY_REGIONS, "ORD,DFW,IAD,SYD,HKG");
       properties.setProperty(PROPERTY_REGION + ".ORD." + ISO3166_CODES, "US-IL");
@@ -111,8 +113,8 @@ public class CloudFilesUSProviderMetadata extends BaseProviderMetadata {
                .version("1.0")
                .view(typeToken(RegionScopedBlobStoreContext.class))
                .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                     .add(CloudIdentityAuthenticationApiModule.class)
                      .add(CloudIdentityAuthenticationModule.class)
+                     .add(ServiceCatalogModule.class)
                      .add(RegionModule.class)
                      .add(SwiftTypeAdapters.class)
                      .add(CloudFilesHttpApiModule.class)

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/providers/rackspace-cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/uk/CloudServersUKProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/rackspace-cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/uk/CloudServersUKProviderMetadata.java b/providers/rackspace-cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/uk/CloudServersUKProviderMetadata.java
index b03c593..adfe4bf 100644
--- a/providers/rackspace-cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/uk/CloudServersUKProviderMetadata.java
+++ b/providers/rackspace-cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/uk/CloudServersUKProviderMetadata.java
@@ -20,17 +20,18 @@ import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
 import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
 
 import java.net.URI;
 import java.util.Properties;
 
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.nova.v2_0.NovaApiMetadata;
 import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
 import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 import org.jclouds.rackspace.cloudservers.uk.config.CloudServersUKComputeServiceContextModule;
@@ -44,71 +45,83 @@ import com.google.inject.Module;
  * Implementation of {@link ProviderMetadata} for Rackspace Next Generation Cloud Servers.
  */
 @AutoService(ProviderMetadata.class)
-public class CloudServersUKProviderMetadata extends BaseProviderMetadata {
+public class CloudServersUKProviderMetadata extends BaseProviderMetadata
+{
 
-   public static Builder builder() {
-      return new Builder();
-   }
+    public static Builder builder()
+    {
+        return new Builder();
+    }
 
-   @Override
-   public Builder toBuilder() {
-      return builder().fromProviderMetadata(this);
-   }
+    @Override
+    public Builder toBuilder()
+    {
+        return builder().fromProviderMetadata(this);
+    }
 
-   public CloudServersUKProviderMetadata() {
-      super(builder());
-   }
+    public CloudServersUKProviderMetadata()
+    {
+        super(builder());
+    }
 
-   public CloudServersUKProviderMetadata(Builder builder) {
-      super(builder);
-   }
+    public CloudServersUKProviderMetadata(final Builder builder)
+    {
+        super(builder);
+    }
 
-   public static Properties defaultProperties() {
-      Properties properties = new Properties();
-      properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
-      properties.setProperty(PROPERTY_REGIONS, "LON");
-      properties.setProperty(PROPERTY_REGION + ".LON." + ISO3166_CODES, "GB-SLG");
-      properties.setProperty(TEMPLATE, "imageNameMatches=.*Ubuntu.*");
-      return properties;
-   }
+    public static Properties defaultProperties()
+    {
+        Properties properties = new Properties();
+        properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
+        properties.setProperty(KEYSTONE_VERSION, "2");
+        properties.setProperty(PROPERTY_REGIONS, "LON");
+        properties.setProperty(PROPERTY_REGION + ".LON." + ISO3166_CODES, "GB-SLG");
+        properties.setProperty(TEMPLATE, "imageNameMatches=.*Ubuntu.*");
+        return properties;
+    }
 
-   public static class Builder extends BaseProviderMetadata.Builder {
+    public static class Builder extends BaseProviderMetadata.Builder
+    {
 
-      protected Builder() {
-         id("rackspace-cloudservers-uk")
-         .name("Rackspace Next Generation Cloud Servers UK")
-         .apiMetadata(new NovaApiMetadata().toBuilder()
-                  .identityName("${userName}")
-                  .credentialName("${apiKey}")
-                  .version("2")
-                  .defaultEndpoint("https://lon.identity.api.rackspacecloud.com/v2.0/")
-                  .endpointName("identity service url ending in /v2.0/")
-                  .documentation(URI.create("http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_preface.html#webhelp-currentid"))
-                  .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                              .add(CloudIdentityAuthenticationApiModule.class)
-                                              .add(CloudIdentityAuthenticationModule.class)
-                                              .add(RegionModule.class)
-                                              .add(NovaParserModule.class)
-                                              .add(CloudServersUKHttpApiModule.class)
-                                              .add(CloudServersUKComputeServiceContextModule.class).build())
-                  .build())
-         .homepage(URI.create("http://www.rackspace.co.uk/opencloud"))
-         .console(URI.create("https://mycloud.rackspace.co.uk/"))
-         .linkedServices("rackspace-cloudservers-uk", "cloudfiles-swift-uk")
-         .iso3166Codes("GB-SLG")
-         .endpoint("https://lon.identity.api.rackspacecloud.com/v2.0/")
-         .defaultProperties(CloudServersUKProviderMetadata.defaultProperties());
-      }
+        protected Builder()
+        {
+            id("rackspace-cloudservers-uk")
+                .name("Rackspace Next Generation Cloud Servers UK")
+                .apiMetadata(
+                    new NovaApiMetadata()
+                        .toBuilder()
+                        .identityName("${userName}")
+                        .credentialName("${apiKey}")
+                        .version("2")
+                        .defaultEndpoint("https://lon.identity.api.rackspacecloud.com/v2.0/")
+                        .endpointName("identity service url ending in /v2.0/")
+                        .documentation(
+                            URI.create("http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_preface.html#webhelp-currentid"))
+                        .defaultModules(
+                            ImmutableSet.<Class< ? extends Module>>builder()
+                                .add(CloudIdentityAuthenticationModule.class)
+                                .add(ServiceCatalogModule.class).add(RegionModule.class)
+                                .add(NovaParserModule.class).add(CloudServersUKHttpApiModule.class)
+                                .add(CloudServersUKComputeServiceContextModule.class).build())
+                        .build()).homepage(URI.create("http://www.rackspace.co.uk/opencloud"))
+                .console(URI.create("https://mycloud.rackspace.co.uk/"))
+                .linkedServices("rackspace-cloudservers-uk", "cloudfiles-swift-uk")
+                .iso3166Codes("GB-SLG")
+                .endpoint("https://lon.identity.api.rackspacecloud.com/v2.0/")
+                .defaultProperties(CloudServersUKProviderMetadata.defaultProperties());
+        }
 
-      @Override
-      public CloudServersUKProviderMetadata build() {
-         return new CloudServersUKProviderMetadata(this);
-      }
+        @Override
+        public CloudServersUKProviderMetadata build()
+        {
+            return new CloudServersUKProviderMetadata(this);
+        }
 
-      @Override
-      public Builder fromProviderMetadata(ProviderMetadata in) {
-         super.fromProviderMetadata(in);
-         return this;
-      }
-   }
+        @Override
+        public Builder fromProviderMetadata(final ProviderMetadata in)
+        {
+            super.fromProviderMetadata(in);
+            return this;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/providers/rackspace-cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/us/CloudServersUSProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/rackspace-cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/us/CloudServersUSProviderMetadata.java b/providers/rackspace-cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/us/CloudServersUSProviderMetadata.java
index 2d247dc..5262188 100644
--- a/providers/rackspace-cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/us/CloudServersUSProviderMetadata.java
+++ b/providers/rackspace-cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/us/CloudServersUSProviderMetadata.java
@@ -16,21 +16,22 @@
  */
 package org.jclouds.rackspace.cloudservers.us;
 
+import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
 import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
 import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
 
 import java.net.URI;
 import java.util.Properties;
 
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.nova.v2_0.NovaApiMetadata;
 import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
 import org.jclouds.providers.ProviderMetadata;
 import org.jclouds.providers.internal.BaseProviderMetadata;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 import org.jclouds.rackspace.cloudservers.us.config.CloudServersUSComputeServiceContextModule;
@@ -66,6 +67,7 @@ public class CloudServersUSProviderMetadata extends BaseProviderMetadata {
    public static Properties defaultProperties() {
       Properties properties = new Properties();
       properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       properties.setProperty(PROPERTY_REGIONS, "ORD,DFW,IAD,SYD,HKG");
       properties.setProperty(PROPERTY_REGION + ".ORD." + ISO3166_CODES, "US-IL");
       properties.setProperty(PROPERTY_REGION + ".DFW." + ISO3166_CODES, "US-TX");
@@ -94,8 +96,8 @@ public class CloudServersUSProviderMetadata extends BaseProviderMetadata {
                   .documentation(
                         URI.create("http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/index.html"))
                   .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                        .add(CloudIdentityAuthenticationApiModule.class)
                         .add(CloudIdentityAuthenticationModule.class)
+                        .add(ServiceCatalogModule.class)
                         .add(RegionModule.class)
                         .add(NovaParserModule.class)
                         .add(CloudServersUSHttpApiModule.class)


[6/8] jclouds git commit: Initial work towards Keystone V3 authentication

Posted by na...@apache.org.
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/ServiceCatalogModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/ServiceCatalogModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/ServiceCatalogModule.java
new file mode 100644
index 0000000..9761da0
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/ServiceCatalogModule.java
@@ -0,0 +1,160 @@
+/*
+ * 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.keystone.catalog.config;
+
+import static org.jclouds.util.Suppliers2.getLastValueInMap;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.location.Provider;
+import org.jclouds.location.suppliers.ImplicitLocationSupplier;
+import org.jclouds.location.suppliers.LocationsSupplier;
+import org.jclouds.location.suppliers.RegionIdToURISupplier;
+import org.jclouds.location.suppliers.RegionIdsSupplier;
+import org.jclouds.location.suppliers.all.RegionToProvider;
+import org.jclouds.location.suppliers.derived.RegionIdsFromRegionIdToURIKeySet;
+import org.jclouds.location.suppliers.implicit.FirstRegion;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.suppliers.LocationIdToURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURISupplier;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
+import org.jclouds.openstack.keystone.v2_0.catalog.V2ServiceCatalog;
+import org.jclouds.openstack.keystone.v3.catalog.V3ServiceCatalog;
+import org.jclouds.rest.annotations.ApiVersion;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Maps;
+import com.google.inject.AbstractModule;
+import com.google.inject.Injector;
+import com.google.inject.Provides;
+import com.google.inject.Scopes;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+
+public class ServiceCatalogModule extends AbstractModule {
+
+   @Override
+   protected void configure() {
+      
+   }
+   
+   @Provides
+   @Singleton
+   protected final Supplier<List<ServiceEndpoint>> provideServiceCatalog(Injector i,
+         @Named(KeystoneProperties.KEYSTONE_VERSION) String keystoneVersion) {
+      Map<String, Supplier<List<ServiceEndpoint>>> serviceCatalogs = Maps.newHashMap();
+      serviceCatalogs.put("2", i.getInstance(V2ServiceCatalog.class));
+      serviceCatalogs.put("3", i.getInstance(V3ServiceCatalog.class));
+      return serviceCatalogs.get(keystoneVersion);
+   }
+   
+   /**
+    * For global services who have no regions, such as DNS. To use, do the following
+    * <ol>
+    * <li>add this module to your {@link org.jclouds.apis.ApiMetadata#getDefaultModules()}</li>
+    * <li>create a service-specific annotation, such as {@code @CloudDNS}, and make sure that has the meta-annotation
+    * {@link javax.inject.Qualifier}</li>
+    * <li>add the above annotation to any {@code Api} classes by placing it on the type. ex.
+    * {@code @Endpoint(CloudDNS.class)}</li>
+    * <li>add the following to your {@link org.jclouds.rest.config.RestClientModule}</li>
+    *
+    * <pre>
+    * bind(new TypeLiteral&lt;Supplier&lt;URI&gt;&gt;() {
+    * }).annotatedWith(CloudDNS.class).to(new TypeLiteral&lt;Supplier&lt;URI&gt;&gt;() {
+    * });
+    * </pre>
+    */
+   public static class ProviderModule extends AbstractModule {
+      @Override
+      protected void configure() {
+         install(new FactoryModuleBuilder().build(LocationIdToURIFromAccessForTypeAndVersion.Factory.class));
+      }
+
+      @Provides
+      @Singleton
+      protected final Supplier<URI> provideZoneIdToURISupplierForApiVersion(
+            @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
+            LocationIdToURIFromAccessForTypeAndVersion.Factory factory) {
+         return getLastValueInMap(factory.createForApiTypeAndVersion(serviceType, apiVersion));
+      }
+
+      @Provides
+      @Singleton
+      final Function<ServiceEndpoint, String> provideProvider(@Provider final String provider) {
+         return new Function<ServiceEndpoint, String>() {
+            @Override
+            public String apply(ServiceEndpoint in) {
+               return provider;
+            }
+         };
+      }
+   }
+
+   public static class RegionModule extends AbstractModule {
+      @Override
+      protected void configure() {
+         install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
+               RegionIdToURIFromAccessForTypeAndVersion.class).build(RegionIdToURISupplier.Factory.class));
+         install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
+               RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
+         // Dynamically build the region list as opposed to from properties
+         bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class);
+         bind(ImplicitLocationSupplier.class).to(FirstRegion.class).in(Scopes.SINGLETON);
+         bind(LocationsSupplier.class).to(RegionToProvider.class).in(Scopes.SINGLETON);
+      }
+
+      @Provides
+      @Singleton
+      protected final RegionIdToURISupplier guiceProvideRegionIdToURISupplierForApiVersion(
+              @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
+              RegionIdToURISupplier.Factory factory) {
+         return provideRegionIdToURISupplierForApiVersion(serviceType, apiVersion, factory);
+      }
+
+      // Supply the region to id map from keystone, based on the servicetype and
+      // api version in config
+      protected RegionIdToURISupplier provideRegionIdToURISupplierForApiVersion(
+            @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
+            RegionIdToURISupplier.Factory factory) {
+         return factory.createForApiTypeAndVersion(serviceType, apiVersion);
+      }
+
+      @Provides
+      @Singleton
+      protected final RegionIdToAdminURISupplier guiceProvideRegionIdToAdminURISupplierForApiVersion(
+              @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
+              RegionIdToAdminURISupplier.Factory factory) {
+         return provideRegionIdToAdminURISupplierForApiVersion(serviceType, apiVersion, factory);
+      }
+
+      // Supply the region to id to AdminURL map from keystone, based on the
+      // servicetype and api version in config
+      protected RegionIdToAdminURISupplier provideRegionIdToAdminURISupplierForApiVersion(
+            @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
+            RegionIdToAdminURISupplier.Factory factory) {
+         return factory.createForApiTypeAndVersion(serviceType, apiVersion);
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/AdminEndpointResolutionStrategy.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/AdminEndpointResolutionStrategy.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/AdminEndpointResolutionStrategy.java
new file mode 100644
index 0000000..3ee1d78
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/AdminEndpointResolutionStrategy.java
@@ -0,0 +1,27 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import com.google.inject.ImplementedBy;
+
+/**
+ * Given a sets of endpoints for a particular service and version, return the
+ * URL of the admin endpoint to be used to connect to the service.
+ */
+@ImplementedBy(AdminURL.class)
+public interface AdminEndpointResolutionStrategy extends ServiceEndpointResolutionStrategy {
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/AdminURL.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/AdminURL.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/AdminURL.java
new file mode 100644
index 0000000..b727ca1
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/AdminURL.java
@@ -0,0 +1,34 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.ADMIN;
+
+import javax.inject.Singleton;
+
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+
+import com.google.common.base.Predicate;
+
+@Singleton
+public class AdminURL extends BaseEndpointResolutionStrategy implements AdminEndpointResolutionStrategy {
+
+   @Override
+   protected Predicate<ServiceEndpoint> filter() {
+      return withIface(ADMIN);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/BaseEndpointResolutionStrategy.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/BaseEndpointResolutionStrategy.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/BaseEndpointResolutionStrategy.java
new file mode 100644
index 0000000..23fe16d
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/BaseEndpointResolutionStrategy.java
@@ -0,0 +1,62 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import static com.google.common.collect.Iterables.tryFind;
+
+import java.net.URI;
+import java.util.Collection;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+
+/**
+ * Resolves the endpoint to be used to connect to a service based on a given
+ * predicate.
+ */
+public abstract class BaseEndpointResolutionStrategy implements ServiceEndpointResolutionStrategy {
+
+   protected abstract Predicate<ServiceEndpoint> filter();
+
+   @Nullable
+   @Override
+   public Supplier<URI> apply(Collection<ServiceEndpoint> input) {
+      Predicate<ServiceEndpoint> filter = filter();
+      Optional<ServiceEndpoint> serviceEndpoint = tryFind(input, filter);
+      return Suppliers.ofInstance(serviceEndpoint.isPresent() ? serviceEndpoint.get().url() : null);
+   }
+
+   protected static Predicate<ServiceEndpoint> withIface(final Interface iface) {
+      return new Predicate<ServiceEndpoint>() {
+         @Override
+         public boolean apply(ServiceEndpoint input) {
+            return input.iface().equals(iface);
+         }
+
+         @Override
+         public String toString() {
+            return "interface(" + iface.name().toLowerCase() + ")";
+         }
+      };
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/InternalURL.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/InternalURL.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/InternalURL.java
new file mode 100644
index 0000000..dfe44e3
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/InternalURL.java
@@ -0,0 +1,34 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.INTERNAL;
+
+import javax.inject.Singleton;
+
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+
+import com.google.common.base.Predicate;
+
+@Singleton
+public class InternalURL extends BaseEndpointResolutionStrategy {
+
+   @Override
+   protected Predicate<ServiceEndpoint> filter() {
+      return withIface(INTERNAL);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/PublicURLOrInternal.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/PublicURLOrInternal.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/PublicURLOrInternal.java
new file mode 100644
index 0000000..cbf01f9
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/PublicURLOrInternal.java
@@ -0,0 +1,66 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import static com.google.common.base.Predicates.or;
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.INTERNAL;
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.PUBLIC;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.inject.Singleton;
+
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+
+@Singleton
+public class PublicURLOrInternal extends BaseEndpointResolutionStrategy {
+
+   @Override
+   public Supplier<URI> apply(Collection<ServiceEndpoint> input) {
+      List<ServiceEndpoint> publicEndpointsFirst = new ArrayList<ServiceEndpoint>(input);
+      Collections.sort(publicEndpointsFirst, PublicInterfacesFirst);
+      return super.apply(publicEndpointsFirst);
+   }
+
+   @Override
+   protected Predicate<ServiceEndpoint> filter() {
+      return or(withIface(PUBLIC), withIface(INTERNAL));
+   }
+
+   private static final Comparator<ServiceEndpoint> PublicInterfacesFirst = new Comparator<ServiceEndpoint>() {
+      @Override
+      public int compare(ServiceEndpoint left, ServiceEndpoint right) {
+         // We only care about public interfaces, since the collection will be
+         // filtered only by public or internal ones
+         if (PUBLIC.equals(left.iface())) {
+            return -1;
+         } else if (PUBLIC.equals(right.iface())) {
+            return 1;
+         } else {
+            return 0;
+         }
+      };
+   };
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ReturnRegionOrProvider.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ReturnRegionOrProvider.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ReturnRegionOrProvider.java
new file mode 100644
index 0000000..db1d314
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ReturnRegionOrProvider.java
@@ -0,0 +1,38 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.location.Provider;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+
+@Singleton
+public class ReturnRegionOrProvider implements ServiceEndpointToRegion {
+   private final String provider;
+
+   @Inject
+   ReturnRegionOrProvider(@Provider String provider) {
+      this.provider = provider;
+   }
+
+   @Override
+   public String apply(ServiceEndpoint input) {
+      return input.regionId() != null ? input.regionId() : provider;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ServiceEndpointResolutionStrategy.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ServiceEndpointResolutionStrategy.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ServiceEndpointResolutionStrategy.java
new file mode 100644
index 0000000..da8b654
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ServiceEndpointResolutionStrategy.java
@@ -0,0 +1,35 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import java.net.URI;
+import java.util.Collection;
+
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.inject.ImplementedBy;
+
+/**
+ * Given a sets of endpoints for a particular service and version, return the
+ * URL to be used to connect to the service.
+ */
+@ImplementedBy(PublicURLOrInternal.class)
+public interface ServiceEndpointResolutionStrategy extends Function<Collection<ServiceEndpoint>, Supplier<URI>> {
+   
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ServiceEndpointToRegion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ServiceEndpointToRegion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ServiceEndpointToRegion.java
new file mode 100644
index 0000000..c1ed3f1
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/functions/ServiceEndpointToRegion.java
@@ -0,0 +1,27 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+
+import com.google.common.base.Function;
+import com.google.inject.ImplementedBy;
+
+@ImplementedBy(ReturnRegionOrProvider.class)
+public interface ServiceEndpointToRegion extends Function<ServiceEndpoint, String> {
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java
new file mode 100644
index 0000000..8adf561
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.keystone.catalog.suppliers;
+
+import static com.google.common.collect.Iterables.any;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.isEmpty;
+import static com.google.common.collect.Maps.transformValues;
+import static com.google.common.collect.Multimaps.asMap;
+import static com.google.common.collect.Multimaps.index;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.annotation.Resource;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointResolutionStrategy;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointToRegion;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Multimap;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+
+public class LocationIdToURIFromAccessForTypeAndVersion implements Supplier<Map<String, Supplier<URI>>> {
+
+   public interface Factory {
+      
+      LocationIdToURIFromAccessForTypeAndVersion createForApiTypeAndVersion(@Assisted("apiType") String apiType,
+            @Nullable @Assisted("apiVersion") String apiVersion) throws NoSuchElementException;
+   }
+
+   @Resource
+   protected Logger logger = Logger.NULL;
+
+   protected final Supplier<List<ServiceEndpoint>> serviceEndpoints;
+   protected final ServiceEndpointResolutionStrategy resolveServiceEndpointURI;
+   protected final ServiceEndpointToRegion serviceEndpointToRegion;
+   protected final String apiType;
+   protected final String apiVersion;
+
+   @Inject
+   LocationIdToURIFromAccessForTypeAndVersion(Supplier<List<ServiceEndpoint>> serviceEndpoints,
+         ServiceEndpointResolutionStrategy resolveServiceEndpointURI, ServiceEndpointToRegion serviceEndpointToRegion,
+         @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
+      this.serviceEndpoints = serviceEndpoints;
+      this.resolveServiceEndpointURI = resolveServiceEndpointURI;
+      this.serviceEndpointToRegion = serviceEndpointToRegion;
+      this.apiType = apiType;
+      this.apiVersion = apiVersion;
+   }
+
+   @Override
+   public Map<String, Supplier<URI>> get() {
+      List<ServiceEndpoint> endpoints = serviceEndpoints.get();
+
+      // Filter endpoints by service type
+      Iterable<ServiceEndpoint> endpointsForType = filter(endpoints, apiTypeEquals);
+      if (isEmpty(endpointsForType)) {
+         throw new NoSuchElementException(String.format("no endpoints for apiType %s in service endpoints %s", apiType,
+               endpoints));
+      }
+      
+      // Check if there are endpoints for a particular version, if specified and
+      // there are versioned endpoints
+      boolean checkVersionId = apiVersion != null && any(endpointsForType, versionAware);
+      Predicate<ServiceEndpoint> versionFilter = checkVersionId ? apiVersionEqualsVersionId : Predicates.<ServiceEndpoint> alwaysTrue();
+      Iterable<ServiceEndpoint> endpointsForTypeAndVersion = filter(endpointsForType, versionFilter);
+      if (isEmpty(endpointsForTypeAndVersion)) {
+         throw new NoSuchElementException(String.format(
+               "no service endpoints for apiType %s are of version %s, or version agnostic: %s", apiType, apiVersion,
+               endpointsForType));
+      }
+
+      logger.debug("service endpoints for apiType %s and version %s: %s", apiType, apiVersion,
+            endpointsForTypeAndVersion);
+      
+      Multimap<String, ServiceEndpoint> locationToServiceEndpoints = index(endpointsForTypeAndVersion,
+            serviceEndpointToRegion);
+      return transformValues(asMap(locationToServiceEndpoints), resolveServiceEndpointURI);
+   }
+
+   private final Predicate<ServiceEndpoint> apiVersionEqualsVersionId = new Predicate<ServiceEndpoint>() {
+      @Override
+      public boolean apply(ServiceEndpoint input) {
+         return input.version().equals(apiVersion);
+      }
+   };
+
+   private final Predicate<ServiceEndpoint> versionAware = new Predicate<ServiceEndpoint>() {
+      @Override
+      public boolean apply(ServiceEndpoint input) {
+         return input.version() != null;
+      }
+   };
+
+   private final Predicate<ServiceEndpoint> apiTypeEquals = new Predicate<ServiceEndpoint>() {
+      @Override
+      public boolean apply(ServiceEndpoint input) {
+         return input.type().equals(apiType);
+      }
+   };
+
+   @Override
+   public String toString() {
+      return "locationIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java
new file mode 100644
index 0000000..740b7a3
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java
@@ -0,0 +1,44 @@
+/*
+ * 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.keystone.catalog.suppliers;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.functions.AdminEndpointResolutionStrategy;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointToRegion;
+
+import com.google.common.base.Supplier;
+import com.google.inject.assistedinject.Assisted;
+
+public class RegionIdToAdminURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
+      RegionIdToAdminURISupplier {
+   @Inject
+   public RegionIdToAdminURIFromAccessForTypeAndVersion(Supplier<List<ServiceEndpoint>> serviceEndpoints,
+         AdminEndpointResolutionStrategy resolveServiceEndpointURI, ServiceEndpointToRegion serviceEndpointToRegion,
+         @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
+      super(serviceEndpoints, resolveServiceEndpointURI, serviceEndpointToRegion, apiType, apiVersion);
+   }
+
+   @Override
+   public String toString() {
+      return "regionIdToAdminURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURISupplier.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURISupplier.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURISupplier.java
new file mode 100644
index 0000000..0f70205
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURISupplier.java
@@ -0,0 +1,37 @@
+/*
+ * 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.keystone.catalog.suppliers;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.base.Supplier;
+import com.google.inject.ImplementedBy;
+import com.google.inject.assistedinject.Assisted;
+
+@ImplementedBy(RegionIdToAdminURIFromAccessForTypeAndVersion.class)
+public interface RegionIdToAdminURISupplier extends Supplier<Map<String, Supplier<URI>>> {
+
+   interface Factory {
+
+      RegionIdToAdminURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType,
+               @Nullable @Assisted("apiVersion") String apiVersion) throws NoSuchElementException;
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java
new file mode 100644
index 0000000..d40b4af
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java
@@ -0,0 +1,46 @@
+/*
+ * 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.keystone.catalog.suppliers;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.suppliers.RegionIdToURISupplier;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointResolutionStrategy;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointToRegion;
+
+import com.google.common.base.Supplier;
+import com.google.inject.assistedinject.Assisted;
+
+public class RegionIdToURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
+      RegionIdToURISupplier {
+
+   @Inject
+   public RegionIdToURIFromAccessForTypeAndVersion(Supplier<List<ServiceEndpoint>> serviceEndpoints,
+         ServiceEndpointResolutionStrategy resolveServiceEndpointURI, ServiceEndpointToRegion serviceEndpointToRegion,
+         @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
+      super(serviceEndpoints, resolveServiceEndpointURI, serviceEndpointToRegion, apiType, apiVersion);
+   }
+
+   @Override
+   public String toString() {
+      return "regionIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/config/KeystoneProperties.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/config/KeystoneProperties.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/config/KeystoneProperties.java
new file mode 100644
index 0000000..ece0129
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/config/KeystoneProperties.java
@@ -0,0 +1,83 @@
+/*
+ * 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.keystone.config;
+
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
+
+/**
+ * Configuration properties and constants used in Keystone connections.
+ */
+public final class KeystoneProperties {
+
+   /**
+    * Type of credentials used to log into the auth service.
+    *
+    * <h3>valid values</h3>
+    * <ul>
+    * <li>apiAccessKeyCredentials</li>
+    * <li>passwordCredentials</li>
+    * <li>tokenCredentials</li>
+    * </ul>
+    *
+    * @see CredentialTypes
+    * @see <a href=
+    *      "http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_Service_API_Api_Operations.html"
+    *      />
+    */
+   public static final String CREDENTIAL_TYPE = "jclouds.keystone.credential-type";
+
+   /**
+    * set this property to specify the tenant id of the authenticated user.
+    * Cannot be used simultaneously with {@link #TENANT_NAME}
+    *
+    * @see <a href="http://wiki.openstack.org/CLIAuth">openstack docs</a>
+    */
+   public static final String TENANT_ID = "jclouds.keystone.tenant-id";
+
+   /**
+    * set this property to specify the tenant name of the authenticated user.
+    * Cannot be used simultaneously with {@link #TENANT_ID}
+    *
+    * @see <a href="http://wiki.openstack.org/CLIAuth">openstack docs</a>
+    */
+   public static final String TENANT_NAME = "jclouds.keystone.tenant-name";
+
+   /**
+    * set this property to {@code true} to designate that the service requires
+    * explicit specification of either {@link #TENANT_NAME} or
+    * {@link #TENANT_ID}
+    *
+    * @see <a href="http://wiki.openstack.org/CLIAuth">openstack docs</a>
+    */
+   public static final String REQUIRES_TENANT = "jclouds.keystone.requires-tenant";
+
+   /**
+    * type of the keystone service. ex. {@code compute}
+    *
+    * @see ServiceType
+    */
+   public static final String SERVICE_TYPE = "jclouds.keystone.service-type";
+   
+   /**
+    * Version of keystone to be used by services. Default: 3.
+    */
+   public static final String KEYSTONE_VERSION = "jclouds.keystone.version";
+
+   private KeystoneProperties() {
+      throw new AssertionError("intentionally unimplemented");
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationApi.java
deleted file mode 100644
index 0ac8a6c..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/AuthenticationApi.java
+++ /dev/null
@@ -1,91 +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.keystone.v2_0;
-
-import java.io.Closeable;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.core.MediaType;
-
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.binders.BindAuthToJsonPayload;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials;
-import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
-import org.jclouds.rest.annotations.MapBinder;
-import org.jclouds.rest.annotations.PayloadParam;
-import org.jclouds.rest.annotations.SelectJson;
-
-import com.google.inject.name.Named;
-
-/**
- * Provides access to the OpenStack Keystone Service API.
- */
-@Consumes(MediaType.APPLICATION_JSON)
-@Path("/tokens")
-public interface AuthenticationApi extends Closeable {
-
-   /**
-    * Authenticate to generate a token.
-    *
-    * @return access with token
-    */
-   @Named("authenticate")
-   @POST
-   @SelectJson("access")
-   @MapBinder(BindAuthToJsonPayload.class)
-   Access authenticateWithTenantNameAndCredentials(@Nullable @PayloadParam("tenantName") String tenantName,
-         PasswordCredentials passwordCredentials);
-
-   /**
-    * Authenticate to generate a token.
-    *
-    * @return access with token
-    */
-   @Named("authenticate")
-   @POST
-   @SelectJson("access")
-   @MapBinder(BindAuthToJsonPayload.class)
-   Access authenticateWithTenantIdAndCredentials(@Nullable @PayloadParam("tenantId") String tenantId,
-         PasswordCredentials passwordCredentials);
-
-   /**
-    * Authenticate to generate a token.
-    *
-    * @return access with token
-    */
-   @Named("authenticate")
-   @POST
-   @SelectJson("access")
-   @MapBinder(BindAuthToJsonPayload.class)
-   Access authenticateWithTenantNameAndCredentials(@Nullable @PayloadParam("tenantName") String tenantName,
-         ApiAccessKeyCredentials apiAccessKeyCredentials);
-
-   /**
-    * Authenticate to generate a token.
-    *
-    * @return access with token
-    */
-   @Named("authenticate")
-   @POST
-   @SelectJson("access")
-   @MapBinder(BindAuthToJsonPayload.class)
-   Access authenticateWithTenantIdAndCredentials(@Nullable @PayloadParam("tenantId") String tenantId,
-         ApiAccessKeyCredentials apiAccessKeyCredentials);
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java
index a06ea13..b8dbbcf 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/KeystoneApiMetadata.java
@@ -16,18 +16,19 @@
  */
 package org.jclouds.openstack.keystone.v2_0;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 
 import java.net.URI;
 import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
-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.auth.config.AuthenticationModule;
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
+import org.jclouds.openstack.keystone.catalog.config.KeystoneAdminURLModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
 import org.jclouds.openstack.keystone.v2_0.config.KeystoneHttpApiModule;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneHttpApiModule.KeystoneAdminURLModule;
 import org.jclouds.openstack.keystone.v2_0.config.KeystoneParserModule;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.rest.internal.BaseHttpApiMetadata;
@@ -59,6 +60,7 @@ public class KeystoneApiMetadata extends BaseHttpApiMetadata<KeystoneApi> {
       Properties properties = BaseHttpApiMetadata.defaultProperties();
       properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
       properties.setProperty(SERVICE_TYPE, ServiceType.IDENTITY);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       return properties;
    }
 
@@ -75,8 +77,8 @@ public class KeystoneApiMetadata extends BaseHttpApiMetadata<KeystoneApi> {
          .defaultEndpoint("http://localhost:5000/v${jclouds.api-version}/")
          .defaultProperties(KeystoneApiMetadata.defaultProperties())
          .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                     .add(AuthenticationApiModule.class)
-                                     .add(KeystoneAuthenticationModule.class)
+                                     .add(AuthenticationModule.class)
+                                     .add(ServiceCatalogModule.class)
                                      .add(KeystoneAdminURLModule.class)
                                      .add(KeystoneParserModule.class)
                                      .add(KeystoneHttpApiModule.class).build());

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/auth/V2AuthenticationApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/auth/V2AuthenticationApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/auth/V2AuthenticationApi.java
new file mode 100644
index 0000000..3efe4f8
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/auth/V2AuthenticationApi.java
@@ -0,0 +1,68 @@
+/*
+ * 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.keystone.v2_0.auth;
+
+import java.io.Closeable;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.openstack.keystone.auth.AuthenticationApi;
+import org.jclouds.openstack.keystone.auth.domain.ApiAccessKeyCredentials;
+import org.jclouds.openstack.keystone.auth.domain.PasswordCredentials;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+import org.jclouds.openstack.keystone.v2_0.binders.BindAuthToJsonPayload;
+import org.jclouds.openstack.keystone.v2_0.domain.Access;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.SelectJson;
+
+import com.google.inject.name.Named;
+
+/**
+ * Provides access to the OpenStack Keystone Service API.
+ */
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/tokens")
+public interface V2AuthenticationApi extends AuthenticationApi, Closeable {
+
+   /**
+    * Authenticate to generate a token.
+    *
+    * @return access with token
+    */
+   @Named("authenticate")
+   @POST
+   @SelectJson("access")
+   @MapBinder(BindAuthToJsonPayload.class)
+   @Override
+   Access authenticatePassword(TenantAndCredentials<PasswordCredentials> credentials);
+
+   /**
+    * Authenticate to generate a token.
+    *
+    * @return access with token
+    */
+   @Named("authenticate")
+   @POST
+   @SelectJson("access")
+   @MapBinder(BindAuthToJsonPayload.class)
+   @Override
+   Access authenticateAccessKey(TenantAndCredentials<ApiAccessKeyCredentials> credentials);
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/binders/BindAuthToJsonPayload.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/binders/BindAuthToJsonPayload.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/binders/BindAuthToJsonPayload.java
index 71ef63d..5661947 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/binders/BindAuthToJsonPayload.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/binders/BindAuthToJsonPayload.java
@@ -16,24 +16,29 @@
  */
 package org.jclouds.openstack.keystone.v2_0.binders;
 
-import com.google.common.base.Predicates;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-import com.google.common.collect.Iterables;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.collect.Iterables.tryFind;
+import static org.jclouds.openstack.keystone.auth.config.CredentialTypes.findCredentialType;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 import org.jclouds.http.HttpRequest;
 import org.jclouds.json.Json;
-import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
+import org.jclouds.openstack.keystone.auth.config.CredentialType;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
 import org.jclouds.rest.MapBinder;
 import org.jclouds.rest.binders.BindToJsonPayload;
 import org.jclouds.rest.internal.GeneratedHttpRequest;
 
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
 
 @Singleton
 public class BindAuthToJsonPayload extends BindToJsonPayload implements MapBinder {
@@ -42,28 +47,35 @@ public class BindAuthToJsonPayload extends BindToJsonPayload implements MapBinde
       super(jsonBinder);
    }
 
-   protected void addCredentialsInArgsOrNull(GeneratedHttpRequest gRequest, Builder<String, Object> builder) {
-      for (Object arg : Iterables.filter(gRequest.getInvocation().getArgs(), Predicates.notNull())) {
-         if (arg.getClass().isAnnotationPresent(CredentialType.class)) {
-            builder.put(arg.getClass().getAnnotation(CredentialType.class).value(), arg);
-         }
-      }
+   protected TenantAndCredentials<?> findCredentialsInArgs(GeneratedHttpRequest gRequest) {
+      Optional<Object> credentials = tryFind(gRequest.getInvocation().getArgs(), instanceOf(TenantAndCredentials.class));
+      return credentials.isPresent() ? (TenantAndCredentials<?>) credentials.get() : null;
    }
 
    @Override
    public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
       checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest,
-               "this binder is only valid for GeneratedHttpRequests!");
+            "this binder is only valid for GeneratedHttpRequests!");
       GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request;
-
       Builder<String, Object> builder = ImmutableMap.builder();
-      addCredentialsInArgsOrNull(gRequest, builder);
-      // TODO: is tenantName permanent? or should we switch to tenantId at some point. seems most tools
-      // still use tenantName
-      if (!Strings.isNullOrEmpty((String) postParams.get("tenantName")))
-         builder.put("tenantName", postParams.get("tenantName"));
-      else if (!Strings.isNullOrEmpty((String) postParams.get("tenantId")))
-          builder.put("tenantId", postParams.get("tenantId"));
+
+      TenantAndCredentials<?> credentials = findCredentialsInArgs(gRequest);
+      if (credentials != null) {
+         CredentialType credentialType = findCredentialType(credentials.credentials().getClass());
+         checkArgument(credentialType != null, "the given credentials must be annotated with @CredentialType");
+
+         builder.put(credentialType.value(), credentials.credentials());
+
+         // TODO: is tenantName permanent? or should we switch to tenantId at
+         // some point. seems most tools still use tenantName
+         if (credentials != null) {
+            if (!Strings.isNullOrEmpty(credentials.tenantId()))
+               builder.put("tenantId", credentials.tenantId());
+            else if (!Strings.isNullOrEmpty(credentials.tenantName()))
+               builder.put("tenantName", credentials.tenantName());
+         }
+      }
+
       R authRequest = super.bindToRequest(request, ImmutableMap.of("auth", builder.build()));
       authRequest.getPayload().setSensitive(true);
       return authRequest;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/catalog/V2ServiceCatalog.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/catalog/V2ServiceCatalog.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/catalog/V2ServiceCatalog.java
new file mode 100644
index 0000000..913b0b5
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/catalog/V2ServiceCatalog.java
@@ -0,0 +1,105 @@
+/*
+ * 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.keystone.v2_0.catalog;
+
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.ADMIN;
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.INTERNAL;
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.PUBLIC;
+
+import java.net.URI;
+import java.util.List;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface;
+import org.jclouds.openstack.keystone.v2_0.domain.Access;
+import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
+import org.jclouds.openstack.keystone.v2_0.domain.Service;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+
+@Singleton
+public class V2ServiceCatalog implements Supplier<List<ServiceEndpoint>> {
+
+   @Resource
+   private Logger logger = Logger.NULL;
+
+   private final Supplier<AuthInfo> authInfo;
+
+   @Inject
+   V2ServiceCatalog(Supplier<AuthInfo> authInfo) {
+      this.authInfo = authInfo;
+   }
+
+   @Override
+   public List<ServiceEndpoint> get() {
+      Access access = (Access) authInfo.get();
+      ImmutableList.Builder<ServiceEndpoint> serviceEndpoints = ImmutableList.builder();
+      for (Service service : access) {
+         for (Endpoint endpoint : service) {
+            if (endpoint.getAdminURL() != null) {
+               serviceEndpoints.add(toServiceEndpoint(service.getType(), ADMIN).apply(endpoint));
+            }
+            if (endpoint.getInternalURL() != null) {
+               serviceEndpoints.add(toServiceEndpoint(service.getType(), INTERNAL).apply(endpoint));
+            }
+            if (endpoint.getPublicURL() != null) {
+               serviceEndpoints.add(toServiceEndpoint(service.getType(), PUBLIC).apply(endpoint));
+            }
+         }
+      }
+
+      return serviceEndpoints.build();
+   }
+
+   private Function<Endpoint, ServiceEndpoint> toServiceEndpoint(final String type, final Interface iface) {
+      return new Function<Endpoint, ServiceEndpoint>() {
+         @Override
+         public ServiceEndpoint apply(Endpoint input) {
+            ServiceEndpoint.Builder builder = ServiceEndpoint.builder().id(input.getId()).iface(iface)
+                  .regionId(input.getRegion()).type(type).version(input.getVersionId());
+
+            switch (iface) {
+               case ADMIN:
+                  builder.url(input.getAdminURL());
+                  break;
+               case INTERNAL:
+                  builder.url(input.getInternalURL());
+                  break;
+               case PUBLIC:
+                  builder.url(input.getPublicURL());
+                  break;
+               case UNRECOGNIZED:
+                  URI url = input.getPublicURL() != null ? input.getPublicURL() : input.getInternalURL();
+                  logger.warn("Unrecognized endpoint interface for %s. Using URL: %s", input, url);
+                  builder.url(url);
+                  break;
+            }
+
+            return builder.build();
+         }
+      };
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/Authentication.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/Authentication.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/Authentication.java
deleted file mode 100644
index d6e5381..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/Authentication.java
+++ /dev/null
@@ -1,31 +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.keystone.v2_0.config;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import javax.inject.Qualifier;
-
-@Retention(value = RetentionPolicy.RUNTIME)
-@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
-@Qualifier
-public @interface Authentication {
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/AuthenticationApiModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/AuthenticationApiModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/AuthenticationApiModule.java
deleted file mode 100644
index 2537d63..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/AuthenticationApiModule.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jclouds.openstack.keystone.v2_0.config;
-
-import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
-
-import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
-
-import com.google.inject.AbstractModule;
-
-public class AuthenticationApiModule extends AbstractModule  {
-
-   @Override
-   protected void configure() {
-      // AuthenticationApi is used directly for filters and retry handlers, so let's bind it explicitly
-      bindHttpApi(binder(), AuthenticationApi.class);
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialType.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialType.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialType.java
deleted file mode 100644
index b0d67cc..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialType.java
+++ /dev/null
@@ -1,38 +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.keystone.v2_0.config;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import javax.inject.Qualifier;
-
-/**
- * @see CredentialTypes
- */
-@Retention(value = RetentionPolicy.RUNTIME)
-@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
-@Qualifier
-public @interface CredentialType {
-   /**
-    * @see CredentialTypes
-    * 
-    */
-   String value();
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialTypes.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialTypes.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialTypes.java
deleted file mode 100644
index c774ae1..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialTypes.java
+++ /dev/null
@@ -1,52 +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.keystone.v2_0.config;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.util.Map;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Maps;
-
-/**
- * Configuration properties and constants used in Keystone connections.
- */
-public class CredentialTypes {
-
-   public static final String API_ACCESS_KEY_CREDENTIALS = "apiAccessKeyCredentials";
-
-   public static final String PASSWORD_CREDENTIALS = "passwordCredentials";
-
-   public static <T> String credentialTypeOf(T input) {
-      Class<?> authenticationType = input.getClass();
-      checkArgument(authenticationType.isAnnotationPresent(CredentialType.class),
-               "programming error: %s should have annotation %s", authenticationType, CredentialType.class.getName());
-      return authenticationType.getAnnotation(CredentialType.class).value();
-   }
-
-   public static <T> Map<String, T> indexByCredentialType(Iterable<T> iterable) {
-      return Maps.uniqueIndex(iterable, new Function<T, String>() {
-
-         @Override
-         public String apply(T input) {
-            return credentialTypeOf(input);
-         }
-
-      });
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java
deleted file mode 100644
index 4d540fd..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java
+++ /dev/null
@@ -1,257 +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.keystone.v2_0.config;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.jclouds.util.Suppliers2.getLastValueInMap;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import org.jclouds.domain.Credentials;
-import org.jclouds.http.HttpRetryHandler;
-import org.jclouds.http.annotation.ClientError;
-import org.jclouds.location.Provider;
-import org.jclouds.location.suppliers.ImplicitLocationSupplier;
-import org.jclouds.location.suppliers.LocationsSupplier;
-import org.jclouds.location.suppliers.RegionIdToURISupplier;
-import org.jclouds.location.suppliers.RegionIdsSupplier;
-import org.jclouds.location.suppliers.ZoneIdToURISupplier;
-import org.jclouds.location.suppliers.ZoneIdsSupplier;
-import org.jclouds.location.suppliers.all.RegionToProvider;
-import org.jclouds.location.suppliers.all.ZoneToProvider;
-import org.jclouds.location.suppliers.derived.RegionIdsFromRegionIdToURIKeySet;
-import org.jclouds.location.suppliers.derived.ZoneIdsFromZoneIdToURIKeySet;
-import org.jclouds.location.suppliers.implicit.FirstRegion;
-import org.jclouds.location.suppliers.implicit.FirstZone;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-import org.jclouds.openstack.keystone.v2_0.functions.AuthenticateApiAccessKeyCredentials;
-import org.jclouds.openstack.keystone.v2_0.functions.AuthenticatePasswordCredentials;
-import org.jclouds.openstack.keystone.v2_0.handlers.RetryOnRenew;
-import org.jclouds.openstack.keystone.v2_0.suppliers.LocationIdToURIFromAccessForTypeAndVersion;
-import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
-import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier;
-import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToURIFromAccessForTypeAndVersion;
-import org.jclouds.openstack.keystone.v2_0.suppliers.ZoneIdToURIFromAccessForTypeAndVersion;
-import org.jclouds.rest.annotations.ApiVersion;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSet.Builder;
-import com.google.inject.AbstractModule;
-import com.google.inject.Injector;
-import com.google.inject.Provides;
-import com.google.inject.Scopes;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
-
-public class KeystoneAuthenticationModule extends AbstractModule {
-
-   /**
-    * For global services who have no regions, such as DNS. To use, do the following
-    * <ol>
-    * <li>add this module to your {@link org.jclouds.apis.ApiMetadata#getDefaultModules()}</li>
-    * <li>create a service-specific annotation, such as {@code @CloudDNS}, and make sure that has the meta-annotation
-    * {@link javax.inject.Qualifier}</li>
-    * <li>add the above annotation to any {@code Api} classes by placing it on the type. ex.
-    * {@code @Endpoint(CloudDNS.class)}</li>
-    * <li>add the following to your {@link org.jclouds.rest.config.RestClientModule}</li>
-    *
-    * <pre>
-    * bind(new TypeLiteral&lt;Supplier&lt;URI&gt;&gt;() {
-    * }).annotatedWith(CloudDNS.class).to(new TypeLiteral&lt;Supplier&lt;URI&gt;&gt;() {
-    * });
-    * </pre>
-    */
-   public static class ProviderModule extends AbstractModule {
-      @Override
-      protected void configure() {
-         install(new FactoryModuleBuilder().build(LocationIdToURIFromAccessForTypeAndVersion.Factory.class));
-      }
-
-      @Provides
-      @Singleton
-      protected final Supplier<URI> provideZoneIdToURISupplierForApiVersion(
-            @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
-            LocationIdToURIFromAccessForTypeAndVersion.Factory factory) {
-         return getLastValueInMap(factory.createForApiTypeAndVersion(serviceType, apiVersion));
-      }
-
-      @Provides
-      @Singleton
-      final Function<Endpoint, String> provideProvider(@Provider final String provider) {
-         return new Function<Endpoint, String>() {
-            @Override
-            public String apply(Endpoint in) {
-               return provider;
-            }
-         };
-      }
-   }
-
-   public static class RegionModule extends AbstractModule {
-      @Override
-      protected void configure() {
-         install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
-               RegionIdToURIFromAccessForTypeAndVersion.class).build(RegionIdToURISupplier.Factory.class));
-         install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
-               RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
-         // dynamically build the region list as opposed to from properties
-         bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class);
-         bind(ImplicitLocationSupplier.class).to(FirstRegion.class).in(Scopes.SINGLETON);
-         bind(LocationsSupplier.class).to(RegionToProvider.class).in(Scopes.SINGLETON);
-      }
-
-      @Provides
-      @Singleton
-      protected final RegionIdToURISupplier guiceProvideRegionIdToURISupplierForApiVersion(
-              @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
-              RegionIdToURISupplier.Factory factory) {
-         return provideRegionIdToURISupplierForApiVersion(serviceType, apiVersion, factory);
-      }
-
-      // supply the region to id map from keystone, based on the servicetype and api version in
-      // config
-      protected RegionIdToURISupplier provideRegionIdToURISupplierForApiVersion(
-            @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
-            RegionIdToURISupplier.Factory factory) {
-         return factory.createForApiTypeAndVersion(serviceType, apiVersion);
-      }
-
-      @Provides
-      @Singleton
-      protected final RegionIdToAdminURISupplier guiceProvideRegionIdToAdminURISupplierForApiVersion(
-              @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
-              RegionIdToAdminURISupplier.Factory factory) {
-         return provideRegionIdToAdminURISupplierForApiVersion(serviceType, apiVersion, factory);
-      }
-
-      // supply the region to id to AdminURL map from keystone, based on the servicetype and api
-      // version in
-      // config
-      protected RegionIdToAdminURISupplier provideRegionIdToAdminURISupplierForApiVersion(
-            @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
-            RegionIdToAdminURISupplier.Factory factory) {
-         return factory.createForApiTypeAndVersion(serviceType, apiVersion);
-      }
-
-   }
-
-   /**
-    * @deprecated All OpenStack APIs rely on regions in jclouds 2.0. To be removed in jclouds 2.0.
-    */
-   @Deprecated
-   public static class ZoneModule extends AbstractModule {
-      @Override
-      protected void configure() {
-         install(new FactoryModuleBuilder().implement(ZoneIdToURISupplier.class,
-               ZoneIdToURIFromAccessForTypeAndVersion.class).build(ZoneIdToURISupplier.Factory.class));
-         // dynamically build the zone list as opposed to from properties
-         bind(ZoneIdsSupplier.class).to(ZoneIdsFromZoneIdToURIKeySet.class);
-         bind(ImplicitLocationSupplier.class).to(FirstZone.class).in(Scopes.SINGLETON);
-         bind(LocationsSupplier.class).to(ZoneToProvider.class).in(Scopes.SINGLETON);
-      }
-
-      // supply the zone to id map from keystone, based on the servicetype and api version in
-      // config
-      @Provides
-      @Singleton
-      protected final ZoneIdToURISupplier provideZoneIdToURISupplierForApiVersion(
-            @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
-            ZoneIdToURISupplier.Factory factory) {
-         return factory.createForApiTypeAndVersion(serviceType, apiVersion);
-      }
-
-   }
-
-   @Override
-   protected void configure() {
-      bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
-   }
-
-   /**
-    * borrowing concurrency code to ensure that caching takes place properly
-    */
-   @Provides
-   @Singleton
-   @Authentication
-   protected final Supplier<String> provideAuthenticationTokenCache(final Supplier<Access> supplier)
-         throws InterruptedException, ExecutionException, TimeoutException {
-      return new Supplier<String>() {
-         @Override
-         public String get() {
-            return supplier.get().getToken().getId();
-         }
-      };
-   }
-
-   @Provides
-   @Singleton
-   protected final Map<String, Function<Credentials, Access>> provideAuthenticationMethods(Injector i) {
-      return authenticationMethods(i);
-   }
-
-   protected Map<String, Function<Credentials, Access>> authenticationMethods(Injector i) {
-      Builder<Function<Credentials, Access>> fns = ImmutableSet.<Function<Credentials, Access>> builder();
-      fns.add(i.getInstance(AuthenticatePasswordCredentials.class));
-      fns.add(i.getInstance(AuthenticateApiAccessKeyCredentials.class));
-      return CredentialTypes.indexByCredentialType(fns.build());
-   }
-
-   @Provides
-   @Singleton
-   protected final Function<Credentials, Access> authenticationMethodForCredentialType(
-         @Named(KeystoneProperties.CREDENTIAL_TYPE) String credentialType,
-         Map<String, Function<Credentials, Access>> authenticationMethods) {
-      checkArgument(authenticationMethods.containsKey(credentialType), "credential type %s not in supported list: %s",
-            credentialType, authenticationMethods.keySet());
-      return authenticationMethods.get(credentialType);
-   }
-
-   // TODO: what is the timeout of the session token? modify default accordingly
-   // PROPERTY_SESSION_INTERVAL is default to 60 seconds, but we have this here at 11 hours for now.
-   @Provides
-   @Singleton
-   public final LoadingCache<Credentials, Access> provideAccessCache(Function<Credentials, Access> getAccess) {
-      return CacheBuilder.newBuilder().expireAfterWrite(11, TimeUnit.HOURS).build(CacheLoader.from(getAccess));
-   }
-
-   // Temporary conversion of a cache to a supplier until there is a single-element cache
-   // http://code.google.com/p/guava-libraries/issues/detail?id=872
-   @Provides
-   @Singleton
-   protected final Supplier<Access> provideAccessSupplier(final LoadingCache<Credentials, Access> cache,
-         @Provider final Supplier<Credentials> creds) {
-      return new Supplier<Access>() {
-         @Override
-         public Access get() {
-            return cache.getUnchecked(creds.get());
-         }
-      };
-   }
-
-}


[4/8] jclouds git commit: Initial work towards Keystone V3 authentication

Posted by na...@apache.org.
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/KeystoneApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/KeystoneApiMetadata.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/KeystoneApiMetadata.java
new file mode 100644
index 0000000..d649563
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/KeystoneApiMetadata.java
@@ -0,0 +1,98 @@
+/*
+ * 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.keystone.v3;
+
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
+
+import java.net.URI;
+import java.util.Properties;
+
+import org.jclouds.apis.ApiMetadata;
+import org.jclouds.openstack.keystone.auth.config.AuthenticationModule;
+import org.jclouds.openstack.keystone.catalog.config.KeystoneAdminURLModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.v2_0.config.KeystoneHttpApiModule;
+import org.jclouds.openstack.keystone.v2_0.config.KeystoneParserModule;
+import org.jclouds.openstack.v2_0.ServiceType;
+import org.jclouds.rest.internal.BaseHttpApiMetadata;
+
+import com.google.auto.service.AutoService;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+
+/**
+ * Implementation of {@link ApiMetadata} for Keystone 3.0 API
+ */
+@AutoService(ApiMetadata.class)
+public class KeystoneApiMetadata extends BaseHttpApiMetadata<KeystoneApi> {
+
+   @Override
+   public Builder<?> toBuilder() {
+      return new ConcreteBuilder().fromApiMetadata(this);
+   }
+
+   public KeystoneApiMetadata() {
+      this(new ConcreteBuilder());
+   }
+
+   protected KeystoneApiMetadata(Builder<?> builder) {
+      super(builder);
+   }
+
+   public static Properties defaultProperties() {
+      Properties properties = BaseHttpApiMetadata.defaultProperties();
+      properties.setProperty(CREDENTIAL_TYPE, org.jclouds.openstack.keystone.auth.config.CredentialTypes.PASSWORD_CREDENTIALS);
+      properties.setProperty(SERVICE_TYPE, ServiceType.IDENTITY);
+      properties.setProperty(KEYSTONE_VERSION, "2");
+      return properties;
+   }
+
+   public abstract static class Builder<T extends Builder<T>> extends BaseHttpApiMetadata.Builder<KeystoneApi, T> {
+
+      protected Builder() {
+          id("openstack-keystone-3")
+         .name("OpenStack Keystone 3.x API")
+         .identityName("${tenantName}:${userName} or ${userName}, if your keystone supports a default tenant")
+         .credentialName("${password}")
+         .endpointName("Keystone base url ending in /v${jclouds.api-version}/")
+         .documentation(URI.create("http://api.openstack.org/"))
+         .version("3")
+         .defaultEndpoint("http://localhost:5000/v${jclouds.api-version}/")
+         .defaultProperties(KeystoneApiMetadata.defaultProperties())
+         .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
+                                     .add(AuthenticationModule.class)
+                                     .add(ServiceCatalogModule.class)
+                                     .add(KeystoneAdminURLModule.class)
+                                     .add(KeystoneParserModule.class)
+                                     .add(KeystoneHttpApiModule.class).build());
+      }
+
+      @Override
+      public KeystoneApiMetadata build() {
+         return new KeystoneApiMetadata(this);
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/auth/V3AuthenticationApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/auth/V3AuthenticationApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/auth/V3AuthenticationApi.java
new file mode 100644
index 0000000..7a84c21
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/auth/V3AuthenticationApi.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.keystone.v3.auth;
+
+import java.io.Closeable;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.openstack.keystone.auth.AuthenticationApi;
+import org.jclouds.openstack.keystone.auth.domain.PasswordCredentials;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+import org.jclouds.openstack.keystone.auth.domain.TokenCredentials;
+import org.jclouds.openstack.keystone.v3.binders.BindPasswordAuthToJsonPayload;
+import org.jclouds.openstack.keystone.v3.binders.BindTokenAuthToJsonPayload;
+import org.jclouds.openstack.keystone.v3.domain.Token;
+import org.jclouds.openstack.keystone.v3.parsers.ParseToken;
+import org.jclouds.rest.annotations.MapBinder;
+import org.jclouds.rest.annotations.ResponseParser;
+
+import com.google.inject.name.Named;
+
+/**
+ * Provides access to the OpenStack Keystone Authentication API.
+ */
+@Consumes(MediaType.APPLICATION_JSON)
+@Path("/auth/tokens")
+public interface V3AuthenticationApi extends AuthenticationApi, Closeable {
+
+   @Named("token:create")
+   @POST
+   @ResponseParser(ParseToken.class)
+   @MapBinder(BindPasswordAuthToJsonPayload.class)
+   @Override
+   Token authenticatePassword(TenantAndCredentials<PasswordCredentials> credentials);
+
+   @Named("token:create")
+   @POST
+   @ResponseParser(ParseToken.class)
+   @MapBinder(BindTokenAuthToJsonPayload.class)
+   @Override
+   Token authenticateToken(TenantAndCredentials<TokenCredentials> credentials);
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindAuthToJsonPayload.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindAuthToJsonPayload.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindAuthToJsonPayload.java
new file mode 100644
index 0000000..f100988
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindAuthToJsonPayload.java
@@ -0,0 +1,64 @@
+/*
+ * 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.keystone.v3.binders;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.instanceOf;
+import static com.google.common.collect.Iterables.tryFind;
+
+import java.util.Map;
+
+import org.jclouds.http.HttpRequest;
+import org.jclouds.json.Json;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+import org.jclouds.openstack.keystone.v3.domain.Auth;
+import org.jclouds.rest.MapBinder;
+import org.jclouds.rest.binders.BindToJsonPayload;
+import org.jclouds.rest.internal.GeneratedHttpRequest;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+
+public abstract class BindAuthToJsonPayload<T> extends BindToJsonPayload implements MapBinder {
+
+   protected BindAuthToJsonPayload(Json jsonBinder) {
+      super(jsonBinder);
+   }
+
+   protected abstract Auth buildAuth(TenantAndCredentials<T> credentials);
+
+   @Override
+   public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
+      checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest,
+            "this binder is only valid for GeneratedHttpRequests!");
+      GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request;
+
+      Optional<Object> authentication = tryFind(gRequest.getInvocation().getArgs(),
+            instanceOf(TenantAndCredentials.class));
+      checkArgument(authentication.isPresent(), "no credentials found in the api call arguments");
+
+      @SuppressWarnings("unchecked")
+      Auth auth = buildAuth((TenantAndCredentials<T>) authentication.get());
+
+      R authRequest = super.bindToRequest(request, ImmutableMap.of("auth", auth));
+      authRequest.getPayload().setSensitive(true);
+
+      return authRequest;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindPasswordAuthToJsonPayload.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindPasswordAuthToJsonPayload.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindPasswordAuthToJsonPayload.java
new file mode 100644
index 0000000..41f64bc
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindPasswordAuthToJsonPayload.java
@@ -0,0 +1,50 @@
+/*
+ * 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.keystone.v3.binders;
+
+import static java.util.Collections.singletonList;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.json.Json;
+import org.jclouds.openstack.keystone.auth.domain.PasswordCredentials;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+import org.jclouds.openstack.keystone.v3.domain.Auth;
+import org.jclouds.openstack.keystone.v3.domain.Auth.Identity;
+import org.jclouds.openstack.keystone.v3.domain.Auth.Identity.PasswordAuth;
+import org.jclouds.openstack.keystone.v3.domain.Auth.Identity.PasswordAuth.UserAuth;
+import org.jclouds.openstack.keystone.v3.domain.Auth.Identity.PasswordAuth.UserAuth.DomainAuth;
+
+@Singleton
+public class BindPasswordAuthToJsonPayload extends BindAuthToJsonPayload<PasswordCredentials> {
+
+   @Inject
+   BindPasswordAuthToJsonPayload(Json jsonBinder) {
+      super(jsonBinder);
+   }
+
+   @Override
+   protected Auth buildAuth(TenantAndCredentials<PasswordCredentials> credentials) {
+      return Auth.create(Identity.create(
+            singletonList("password"),
+            null,
+            PasswordAuth.create(UserAuth.create(credentials.credentials().username(),
+                  DomainAuth.create(credentials.tenantName()), credentials.credentials().password()))));
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindTokenAuthToJsonPayload.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindTokenAuthToJsonPayload.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindTokenAuthToJsonPayload.java
new file mode 100644
index 0000000..9d60fad
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/binders/BindTokenAuthToJsonPayload.java
@@ -0,0 +1,45 @@
+/*
+ * 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.keystone.v3.binders;
+
+import static java.util.Collections.singletonList;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.json.Json;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+import org.jclouds.openstack.keystone.auth.domain.TokenCredentials;
+import org.jclouds.openstack.keystone.v3.domain.Auth;
+import org.jclouds.openstack.keystone.v3.domain.Auth.Identity;
+import org.jclouds.openstack.keystone.v3.domain.Auth.Identity.TokenAuth;
+
+@Singleton
+public class BindTokenAuthToJsonPayload extends BindAuthToJsonPayload<TokenCredentials> {
+
+   @Inject
+   BindTokenAuthToJsonPayload(Json jsonBinder) {
+      super(jsonBinder);
+   }
+
+   @Override
+   protected Auth buildAuth(TenantAndCredentials<TokenCredentials> credentials) {
+      return Auth
+            .create(Identity.create(singletonList("token"), TokenAuth.create(credentials.credentials().id()), null));
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/catalog/V3ServiceCatalog.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/catalog/V3ServiceCatalog.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/catalog/V3ServiceCatalog.java
new file mode 100644
index 0000000..0e86f2b
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/catalog/V3ServiceCatalog.java
@@ -0,0 +1,63 @@
+/*
+ * 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.keystone.v3.catalog;
+
+import java.util.List;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.v3.domain.Catalog;
+import org.jclouds.openstack.keystone.v3.domain.Endpoint;
+import org.jclouds.openstack.keystone.v3.domain.Token;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+
+@Singleton
+public class V3ServiceCatalog implements Supplier<List<ServiceEndpoint>> {
+
+   @Resource
+   private Logger logger = Logger.NULL;
+
+   private final Supplier<AuthInfo> authInfo;
+
+   @Inject
+   V3ServiceCatalog(Supplier<AuthInfo> authInfo) {
+      this.authInfo = authInfo;
+   }
+
+   @Override
+   public List<ServiceEndpoint> get() {
+      Token token = (Token) authInfo.get();
+
+      ImmutableList.Builder<ServiceEndpoint> serviceEndpoints = ImmutableList.builder();
+      for (Catalog catalog : token.catalog()) {
+         for (Endpoint endpoint : catalog.endpoints()) {
+            serviceEndpoints.add(ServiceEndpoint.builder().id(endpoint.id()).iface(endpoint.iface())
+                  .regionId(endpoint.regionId()).type(catalog.type()).url(endpoint.url()).build());
+         }
+      }
+
+      return serviceEndpoints.build();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Auth.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Auth.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Auth.java
new file mode 100644
index 0000000..13c3753
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Auth.java
@@ -0,0 +1,94 @@
+/*
+ * 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.keystone.v3.domain;
+
+import java.util.List;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+import com.google.auto.value.AutoValue;
+
+@AutoValue
+public abstract class Auth {
+   
+   public abstract Identity identity();
+
+   @SerializedNames({ "identity" })
+   public static Auth create(Identity identity) {
+      return new AutoValue_Auth(identity);
+   }
+
+   @AutoValue
+   public abstract static class Identity {
+      
+      public abstract List<String> methods();
+      public abstract TokenAuth token();
+      public abstract PasswordAuth password();
+
+      @SerializedNames({ "methods", "token", "password" })
+      public static Identity create(List<String> methods, TokenAuth token, PasswordAuth password) {
+         return new AutoValue_Auth_Identity(methods, token, password);
+      }
+
+      @AutoValue
+      public abstract static  class TokenAuth {
+         
+         public abstract String id();
+
+         @SerializedNames({ "id" })
+         public static TokenAuth create(String id) {
+            return new AutoValue_Auth_Identity_TokenAuth(id);
+         }
+      }
+
+      @AutoValue
+      public abstract static  class PasswordAuth {
+         
+         public abstract UserAuth user();
+
+         @SerializedNames({ "user" })
+         public static PasswordAuth create(UserAuth user) {
+            return new AutoValue_Auth_Identity_PasswordAuth(user);
+         }
+
+         @AutoValue
+         public abstract static  class UserAuth {
+            
+            public abstract String name();
+            public abstract DomainAuth domain();
+            public abstract String password();
+
+            @SerializedNames({ "name", "domain", "password" })
+            public static UserAuth create(String name, DomainAuth domain, String password) {
+               return new AutoValue_Auth_Identity_PasswordAuth_UserAuth(name, domain, password);
+            }
+
+            @AutoValue
+            public abstract static  class DomainAuth {
+               
+               @Nullable public abstract String name();
+
+               @SerializedNames({ "name" })
+               public static DomainAuth create(String name) {
+                  return new AutoValue_Auth_Identity_PasswordAuth_UserAuth_DomainAuth(name);
+               }
+            }
+         }
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Catalog.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Catalog.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Catalog.java
new file mode 100644
index 0000000..e5977f9
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Catalog.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.keystone.v3.domain;
+
+import java.util.List;
+
+import org.jclouds.json.SerializedNames;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+
+@AutoValue
+public abstract class Catalog {
+
+   public abstract String id();
+
+   public abstract String name();
+
+   public abstract String type();
+
+   public abstract List<Endpoint> endpoints();
+
+   @SerializedNames({"id", "name", "type", "endpoints"})
+   public static Catalog create(String id,
+                                String name,
+                                String type,
+                                List<Endpoint> endpoints
+   ) {
+      return new AutoValue_Catalog(id, name, type, endpoints == null ? ImmutableList.<Endpoint>of() : ImmutableList.copyOf(endpoints));
+   }
+
+   Catalog() {
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Endpoint.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Endpoint.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Endpoint.java
new file mode 100644
index 0000000..5de3d11
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Endpoint.java
@@ -0,0 +1,52 @@
+/*
+ * 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.keystone.v3.domain;
+
+import java.net.URI;
+import java.util.List;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+import org.jclouds.openstack.v2_0.domain.Link;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+
+@AutoValue
+public abstract class Endpoint {
+
+   public abstract String id();
+   public abstract String region();
+   public abstract String regionId();
+
+   @Nullable public abstract String serviceId();
+   public abstract URI url();
+   @Nullable public abstract Boolean enabled();
+   @Nullable public abstract List<Link> links();
+   public abstract String iface();
+
+   @SerializedNames({ "id", "region", "region_id", "service_id", "url", "enabled", "links", "interface" })
+   public static Endpoint create(String id, String region, String regionId, String serviceId, URI url, Boolean enabled,
+         List<Link> links, String iface) {
+      return new AutoValue_Endpoint(id, region, regionId, serviceId, url, enabled,
+            links == null ? ImmutableList.<Link> of() : ImmutableList.copyOf(links), iface);
+   }
+
+   Endpoint() {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Link.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Link.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Link.java
new file mode 100644
index 0000000..0d86069
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Link.java
@@ -0,0 +1,36 @@
+/*
+ * 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.keystone.v3.domain;
+
+import org.jclouds.json.SerializedNames;
+
+import com.google.auto.value.AutoValue;
+
+@AutoValue
+public abstract class Link {
+
+   public abstract String self();
+
+   @SerializedNames({"self"})
+   public static Link create(String self) {
+      return new AutoValue_Link(self);
+   }
+
+   Link() {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Region.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Region.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Region.java
new file mode 100644
index 0000000..22e5d1c
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Region.java
@@ -0,0 +1,46 @@
+/*
+ * 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.keystone.v3.domain;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+import com.google.auto.value.AutoValue;
+
+@AutoValue
+public abstract class Region {
+
+   public abstract String id();
+
+   public abstract String name();
+
+   public abstract Link link();
+
+   @Nullable public abstract String parentRegionId();
+
+   @SerializedNames({"id", "description", "links", "parent_region_id"})
+   public static Region create(String id,
+                               String name,
+                               Link link,
+                               String parentRegionId
+   ) {
+      return new AutoValue_Region(id, name, link, parentRegionId);
+   }
+
+   Region() {
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Token.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Token.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Token.java
new file mode 100644
index 0000000..4c43dd2
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Token.java
@@ -0,0 +1,103 @@
+/*
+ * 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.keystone.v3.domain;
+
+import java.util.Date;
+import java.util.List;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+
+@AutoValue
+public abstract class Token implements AuthInfo {
+
+   @Nullable
+   public abstract String id();
+   public abstract List<String> methods();
+   @Nullable
+   public abstract Date expiresAt();
+   @Nullable
+   public abstract Object extras();
+   @Nullable
+   public abstract List<Catalog> catalog();
+   public abstract List<String> auditIds();
+   public abstract User user();
+   public abstract Date issuedAt();
+   
+   @Override
+   public String getAuthToken() {
+      return id();
+   }
+   @SerializedNames({"id", "methods", "expires_at", "extras", "catalog", "audit_ids", "user", "issued_at"})
+   private static Token create(
+           String id,
+           List<String> methods,
+           Date expiresAt,
+           Object extras,
+           List<Catalog> catalog,
+           List<String> auditIds,
+           User user,
+           Date issuedAt
+   ) {
+      return builder()
+              .id(id)
+              .methods(methods)
+              .expiresAt(expiresAt)
+              .extras(extras)
+              .catalog(catalog)
+              .auditIds(auditIds)
+              .user(user)
+              .issuedAt(issuedAt)
+              .build();
+   }
+
+   public abstract Builder toBuilder();
+
+   public static Builder builder() {
+      return new AutoValue_Token.Builder();
+   }
+
+   @AutoValue.Builder
+   public abstract static class Builder {
+
+      public abstract Builder id(String id);
+      public abstract Builder methods(List<String> methods);
+      public abstract Builder expiresAt(Date expiresAt);
+      public abstract Builder extras(Object extras);
+      public abstract Builder catalog(List<Catalog> catalog);
+      public abstract Builder auditIds(List<String> auditIds);
+      public abstract Builder user(User user);
+      public abstract Builder issuedAt(Date issuedAt);
+
+      abstract List<Catalog> catalog();
+      abstract List<String> methods();
+      abstract List<String> auditIds();
+
+      abstract Token autoBuild();
+
+      public Token build() {
+         return catalog(catalog() != null ? ImmutableList.copyOf(catalog()) : ImmutableList.<Catalog>of())
+                 .methods(methods() != null ? ImmutableList.copyOf(methods()) : ImmutableList.<String>of())
+                 .auditIds(auditIds() != null ? ImmutableList.copyOf(auditIds()) : ImmutableList.<String>of())
+                 .autoBuild();
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/User.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/User.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/User.java
new file mode 100644
index 0000000..33702a9
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/User.java
@@ -0,0 +1,57 @@
+/*
+ * 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.keystone.v3.domain;
+
+import java.util.Date;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+import com.google.auto.value.AutoValue;
+
+@AutoValue
+public abstract class User {
+
+   @AutoValue
+   public abstract static class Domain {
+
+      public abstract String id();
+      public abstract String name();
+
+      @SerializedNames({ "id", "name" })
+      public static Domain create(String id, String name) {
+         return new AutoValue_User_Domain(id, name);
+      }
+   }
+
+   public abstract String id();
+   public abstract String name();
+   @Nullable public abstract Date passwordExpiresAt();
+   public abstract Domain domain();
+
+   @SerializedNames({"id", "name", "password_expires_at", "domain"})
+   public static User create(String id,
+                               String name,
+                               Date passwordExpiresAt,
+                               Domain domain
+   ) {
+      return new AutoValue_User(id, name, passwordExpiresAt, domain);
+   }
+
+   User() {
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/features/TokenApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/features/TokenApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/features/TokenApi.java
new file mode 100644
index 0000000..bba190a
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/features/TokenApi.java
@@ -0,0 +1,132 @@
+/*
+ * 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.keystone.v3.features;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Named;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.MediaType;
+
+import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
+import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.Fallbacks.NullOnNotFoundOr404;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
+import org.jclouds.openstack.keystone.v2_0.domain.User;
+import org.jclouds.openstack.keystone.v3.domain.Region;
+import org.jclouds.openstack.keystone.v3.domain.Token;
+import org.jclouds.openstack.v2_0.services.Identity;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.annotations.RequestFilters;
+import org.jclouds.rest.annotations.SelectJson;
+
+/**
+ * Provides access to the Keystone Admin API.
+ */
+@Consumes(MediaType.APPLICATION_JSON)
+@RequestFilters(AuthenticateRequest.class)
+@org.jclouds.rest.annotations.Endpoint(Identity.class)
+public interface TokenApi {
+
+   /**
+    * Validate a token and, if it is valid, return access information regarding the tenant (though not the service catalog)/
+    *
+    * @return the requested information
+    */
+   @Named("token:get")
+   @GET
+   @SelectJson("token")
+   @Path("/auth/tokens/{token}")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   Token get(@PathParam("token") String token);
+
+   /**
+    * Validate a token and, if it is valid, return access information regarding the tenant (though not the service catalog)/
+    *
+    * @return the requested information
+    */
+   @Named("token:getuser")
+   @GET
+   @SelectJson("user")
+   @Path("/auth/tokens/{token}")
+   @Fallback(NullOnNotFoundOr404.class)
+   @Nullable
+   User getUserOfToken(@PathParam("token") String token);
+
+   /**
+    * Validate a token. This is a high-performance variant of the #getToken() call that does not return any further
+    * information.
+    *
+    * @return true if the token is valid
+    */
+   @Named("token:valid")
+   @HEAD
+   @Path("/auth/tokens/{token}")
+   @Fallback(FalseOnNotFoundOr404.class)
+   boolean isValid(@PathParam("token") String token);
+
+   /**
+    * List all endpoints for a token
+    * <p/>
+    * NOTE: currently not working in openstack ( https://bugs.launchpad.net/keystone/+bug/988672 )
+    *
+    * @return the set of endpoints
+    */
+   @Named("token:listEndpoints")
+   @GET
+   @SelectJson("endpoints")
+   @Path("/{token}/endpoints")
+   @Fallback(EmptySetOnNotFoundOr404.class)
+   Set<Endpoint> listEndpointsForToken(@PathParam("token") String token);
+
+
+   /**
+    * List all endpoints for a token
+    * <p/>
+    * NOTE: currently not working in openstack ( https://bugs.launchpad.net/keystone/+bug/988672 )
+    *
+    * @return the list of endpoints
+    */
+   @Named("token:endpoints")
+   @GET
+   @SelectJson("endpoints")
+   @Path("/endpoints")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<Endpoint> endpoints();
+
+   /**
+    * List all regions for a token
+    * <p/>
+    *
+    * @return the list of regions
+    */
+   @Named("token:regions")
+   @GET
+   @SelectJson("regions")
+   @Path("/regions")
+   @Fallback(EmptyListOnNotFoundOr404.class)
+   List<Region> regions();
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseToken.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseToken.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseToken.java
new file mode 100644
index 0000000..1fd633f
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseToken.java
@@ -0,0 +1,41 @@
+/*
+ * 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.keystone.v3.parsers;
+
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.functions.ParseFirstJsonValueNamed;
+import org.jclouds.json.internal.GsonWrapper;
+import org.jclouds.openstack.keystone.v3.domain.Token;
+
+import com.google.common.collect.Iterables;
+import com.google.inject.Inject;
+import com.google.inject.TypeLiteral;
+
+public class ParseToken extends ParseFirstJsonValueNamed<Token> {
+
+   @Inject
+   ParseToken(GsonWrapper json, TypeLiteral<Token> type, String... nameChoices) {
+      super(json, type, nameChoices);
+   }
+
+   @Override
+   public Token apply(HttpResponse from) {
+      Token token = super.apply(from);
+      String xSubjectToken = Iterables.getOnlyElement(from.getHeaders().get("X-Subject-Token"));
+      return token.toBuilder().id(xSubjectToken).build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/config/InternalUrlModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/config/InternalUrlModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/config/InternalUrlModule.java
deleted file mode 100644
index 71b36cb..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/config/InternalUrlModule.java
+++ /dev/null
@@ -1,35 +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.v2_0.config;
-
-import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierURI;
-import org.jclouds.openstack.keystone.v2_0.functions.InternalURL;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.Singleton;
-
-/**
- * Guice module to configure JClouds in order to use the internal urls to
- * communicate with the services.
- */
-@Singleton
-public class InternalUrlModule extends AbstractModule {
-   @Override
-   protected void configure() {
-      bind(EndpointToSupplierURI.class).to(InternalURL.class);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/features/ExtensionApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/features/ExtensionApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/features/ExtensionApi.java
index 633b327..466bcc9 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/features/ExtensionApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/features/ExtensionApi.java
@@ -28,7 +28,7 @@ import javax.ws.rs.core.MediaType;
 import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.domain.Extension;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/reference/AuthHeaders.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/reference/AuthHeaders.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/reference/AuthHeaders.java
deleted file mode 100644
index 88ea817..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/v2_0/reference/AuthHeaders.java
+++ /dev/null
@@ -1,28 +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.v2_0.reference;
-
-public final class AuthHeaders {
-
-   public static final String AUTH_USER = "X-Auth-User";
-   public static final String AUTH_KEY = "X-Auth-Key";
-   public static final String AUTH_TOKEN = "X-Auth-Token";
-
-   private AuthHeaders() {
-      throw new AssertionError("intentionally unimplemented");
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/config/CredentialTypesTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/config/CredentialTypesTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/config/CredentialTypesTest.java
new file mode 100644
index 0000000..93af93c
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/config/CredentialTypesTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.keystone.auth.config;
+
+import static org.testng.Assert.assertEquals;
+
+import org.jclouds.openstack.keystone.auth.domain.PasswordCredentials;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+@Test(groups = "unit", testName = "CredentialTypesTest")
+public class CredentialTypesTest {
+
+   public void testCredentialTypeOfWhenValid() {
+      assertEquals(
+            CredentialTypes.credentialTypeOf(PasswordCredentials.builder().username("username").password("password")
+                  .build()), CredentialTypes.PASSWORD_CREDENTIALS);
+   }
+
+   @Test(expectedExceptions = IllegalArgumentException.class)
+   public void testCredentialTypeOfWithoutAnnotation() {
+      CredentialTypes.credentialTypeOf("");
+   }
+
+   public void testIndexByCredentialTypeWhenValid() {
+      assertEquals(
+            CredentialTypes.indexByCredentialType(
+                  ImmutableSet.of(PasswordCredentials.builder().username("username").password("password").build()))
+                  .keySet(), ImmutableSet.of(CredentialTypes.PASSWORD_CREDENTIALS));
+   }
+
+   @Test(expectedExceptions = IllegalArgumentException.class)
+   public void testIndexByCredentialTypeWithoutAnnotation() {
+      CredentialTypes.indexByCredentialType(ImmutableSet.of(""));
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/config/ProviderModuleExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/config/ProviderModuleExpectTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/config/ProviderModuleExpectTest.java
new file mode 100644
index 0000000..a11c7de
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/config/ProviderModuleExpectTest.java
@@ -0,0 +1,180 @@
+/*
+ * 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.keystone.auth.config;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.util.Suppliers2.getLastValueInMap;
+import static org.testng.Assert.assertTrue;
+
+import java.io.Closeable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.net.URI;
+import java.util.Properties;
+
+import javax.inject.Qualifier;
+import javax.inject.Singleton;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+
+import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
+import org.jclouds.apis.ApiMetadata;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.json.config.GsonModule.DateAdapter;
+import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
+import org.jclouds.location.suppliers.RegionIdToURISupplier;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.ProviderModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
+import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
+import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestApiExpectTest;
+import org.jclouds.rest.ConfiguresHttpApi;
+import org.jclouds.rest.annotations.ApiVersion;
+import org.jclouds.rest.annotations.Fallback;
+import org.jclouds.rest.config.HttpApiModule;
+import org.jclouds.rest.internal.BaseHttpApiMetadata;
+import org.jclouds.rest.internal.BaseRestApiExpectTest;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+import com.google.inject.Provides;
+
+/**
+ * Tests configuration via {@link ProviderModule}
+ */
+@Test(groups = "unit", testName = "ProviderModuleExpectTest")
+public class ProviderModuleExpectTest extends BaseRestApiExpectTest<ProviderModuleExpectTest.DNSApi> {
+
+   @Retention(RUNTIME)
+   @Target(METHOD)
+   @Qualifier
+   static @interface DNS {
+   }
+
+   @ConfiguresHttpApi
+   public static class DNSHttpApiModule extends HttpApiModule<DNSApi> {
+
+      @Override
+      public void configure() {
+         bind(DateAdapter.class).to(Iso8601DateAdapter.class);
+         super.configure();
+      }
+
+      @Provides
+      @Singleton
+      @DNS
+      protected final Supplier<URI> provideCDNUrl(RegionIdToURISupplier.Factory factory, @ApiVersion String apiVersion) {
+         return getLastValueInMap(factory.createForApiTypeAndVersion("dns", apiVersion));
+      }
+   }
+
+   @org.jclouds.rest.annotations.Endpoint(DNS.class)
+   interface DNSApi extends Closeable {
+      @HEAD
+      @Path("/zones/{zoneName}")
+      @Fallback(FalseOnNotFoundOr404.class)
+      boolean zoneExists(@PathParam("zoneName") String zoneName);
+   }
+
+   public void testDNSEndpointApplied() {
+      KeystoneAuth keystoneAuth = new KeystoneAuth();
+
+      DNSApi api = requestsSendResponses(
+            keystoneAuth.getKeystoneAuthWithUsernameAndPassword(),
+            keystoneAuth.getResponseWithKeystoneAccess(),
+            HttpRequest.builder().method("HEAD").endpoint("http://172.16.0.1:8776/v1/3456/zones/foo.com").build(),
+            HttpResponse.builder().statusCode(200).build());
+      assertTrue(api.zoneExists("foo.com"));
+   }
+
+   private static class DNSApiMetadata extends BaseHttpApiMetadata<DNSApi> {
+
+      @Override
+      public Builder toBuilder() {
+         return new Builder().fromApiMetadata(this);
+      }
+
+      public DNSApiMetadata() {
+         this(new Builder());
+      }
+
+      protected DNSApiMetadata(Builder builder) {
+         super(builder);
+      }
+
+      public static Properties defaultProperties() {
+         Properties properties = BaseHttpApiMetadata.defaultProperties();
+         properties.setProperty(SERVICE_TYPE, "dns");
+         properties.setProperty(KEYSTONE_VERSION, "2");
+         properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
+         return properties;
+      }
+
+      public static class Builder extends BaseHttpApiMetadata.Builder<DNSApi, Builder> {
+
+         protected Builder() {
+            id("dns")
+            .name("DNS API")
+            .identityName("${tenantName}:${userName} or ${userName}, if your keystone supports a default tenant")
+            .credentialName("${password}")
+            .endpointName("Keystone base url ending in /v2.0/")
+            .documentation(URI.create("http://dns"))
+            .version("1.0")
+            .defaultEndpoint("http://localhost:5000/v2.0/")
+            .defaultProperties(DNSApiMetadata.defaultProperties())
+            .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
+                                        .add(AuthenticationModule.class)
+                                        .add(ServiceCatalogModule.class)
+                                        .add(RegionModule.class)
+                                        .add(DNSHttpApiModule.class).build());
+         }
+
+         @Override
+         public DNSApiMetadata build() {
+            return new DNSApiMetadata(this);
+         }
+
+         @Override
+         protected Builder self() {
+            return this;
+         }
+      }
+   }
+
+   @Override
+   public ApiMetadata createApiMetadata() {
+      return new DNSApiMetadata();
+   }
+   
+   public static class KeystoneAuth extends BaseKeystoneRestApiExpectTest<KeystoneApi> {
+      public HttpRequest getKeystoneAuthWithUsernameAndPassword() {
+         return keystoneAuthWithUsernameAndPassword;
+      }
+      
+      public HttpResponse getResponseWithKeystoneAccess() {
+         return responseWithKeystoneAccess;
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/handlers/RetryOnRenewTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/handlers/RetryOnRenewTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/handlers/RetryOnRenewTest.java
new file mode 100644
index 0000000..01611ff
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/handlers/RetryOnRenewTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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.keystone.auth.handlers;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.jclouds.domain.Credentials;
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
+import org.jclouds.io.Payloads;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.testng.annotations.Test;
+
+import com.google.common.cache.LoadingCache;
+
+/**
+ * Tests behavior of {@code RetryOnRenew} handler
+ */
+@Test(groups = "unit", testName = "RetryOnRenewTest")
+public class RetryOnRenewTest {
+   @Test
+   public void test401ShouldRetry() {
+      HttpCommand command = createMock(HttpCommand.class);
+      HttpRequest request = createMock(HttpRequest.class);
+      HttpResponse response = createMock(HttpResponse.class);
+      @SuppressWarnings("unchecked")
+      LoadingCache<Credentials, AuthInfo> cache = createMock(LoadingCache.class);
+      BackoffLimitedRetryHandler backoffHandler = createMock(BackoffLimitedRetryHandler.class);
+
+      expect(command.getCurrentRequest()).andReturn(request);
+
+      cache.invalidateAll();
+      expectLastCall();
+
+      expect(response.getPayload()).andReturn(Payloads.newStringPayload("")).anyTimes();
+      expect(response.getStatusCode()).andReturn(401).atLeastOnce();
+
+      replay(command);
+      replay(response);
+      replay(cache);
+      replay(backoffHandler);
+
+      RetryOnRenew retry = new RetryOnRenew(cache, backoffHandler);
+
+      assertTrue(retry.shouldRetryRequest(command, response));
+
+      verify(command);
+      verify(response);
+      verify(cache);
+   }
+
+   @Test
+   public void test401ShouldRetry4Times() {
+      HttpCommand command = createMock(HttpCommand.class);
+      HttpRequest request = createMock(HttpRequest.class);
+      HttpResponse response = createMock(HttpResponse.class);
+
+      @SuppressWarnings("unchecked")
+      LoadingCache<Credentials, AuthInfo> cache = createMock(LoadingCache.class);
+      BackoffLimitedRetryHandler backoffHandler = createMock(BackoffLimitedRetryHandler.class);
+
+      expect(command.getCurrentRequest()).andReturn(request).anyTimes();
+      expect(request.getHeaders()).andStubReturn(null);
+
+      cache.invalidateAll();
+      expectLastCall().anyTimes();
+
+      expect(response.getPayload()).andReturn(Payloads.newStringPayload("")).anyTimes();
+      expect(response.getStatusCode()).andReturn(401).anyTimes();
+
+      replay(command, request, response, cache);
+
+      RetryOnRenew retry = new RetryOnRenew(cache, backoffHandler);
+
+      for (int i = 0; i < RetryOnRenew.NUM_RETRIES - 1; ++i) {
+         assertTrue(retry.shouldRetryRequest(command, response), "Expected retry to succeed");
+      }
+
+      assertFalse(retry.shouldRetryRequest(command, response), "Expected retry to fail on attempt " + RetryOnRenew.NUM_RETRIES);
+
+      verify(command, response, cache);
+   }
+
+   @Test
+   public void test408ShouldRetry() {
+      HttpCommand command = createMock(HttpCommand.class);
+      HttpResponse response = createMock(HttpResponse.class);
+      @SuppressWarnings("unchecked")
+      LoadingCache<Credentials, AuthInfo> cache = createMock(LoadingCache.class);
+      BackoffLimitedRetryHandler backoffHandler = createMock(BackoffLimitedRetryHandler.class);
+
+      expect(backoffHandler.shouldRetryRequest(command, response)).andReturn(true).once();
+      expect(response.getStatusCode()).andReturn(408).once();
+
+      replay(command);
+      replay(response);
+      replay(cache);
+      replay(backoffHandler);
+
+      RetryOnRenew retry = new RetryOnRenew(cache, backoffHandler);
+
+      assertTrue(retry.shouldRetryRequest(command, response));
+
+      verify(command);
+      verify(response);
+      verify(cache);
+      verify(backoffHandler);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
new file mode 100644
index 0000000..91146b0
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.keystone.auth.suppliers;
+
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.inject.Singleton;
+
+import org.jclouds.location.Provider;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.suppliers.LocationIdToURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.v2_0.catalog.V2ServiceCatalog;
+import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
+import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Provides;
+import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+
+@Test(groups = "unit", testName = "LocationIdToURIFromAccessForTypeAndVersionTest")
+public class LocationIdToURIFromAccessForTypeAndVersionTest {
+   private final LocationIdToURIFromAccessForTypeAndVersion.Factory factory = Guice.createInjector(
+         new AbstractModule() {
+
+            @Override
+            protected void configure() {
+               bindConstant().annotatedWith(Provider.class).to("openstack-keystone");
+               bind(new TypeLiteral<Supplier<URI>>() {
+               }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
+               install(new FactoryModuleBuilder().implement(LocationIdToURIFromAccessForTypeAndVersion.class,
+                     LocationIdToURIFromAccessForTypeAndVersion.class).build(
+                     LocationIdToURIFromAccessForTypeAndVersion.Factory.class));
+               // We test against a 2.0 service catalog but it is OK for the purpose of this test
+               bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
+               }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);
+            }
+
+            @Provides
+            @Singleton
+            public Supplier<AuthInfo> provide() {
+               return Suppliers.<AuthInfo> ofInstance(new ParseAccessTest().expected());
+            }
+
+         }).getInstance(LocationIdToURIFromAccessForTypeAndVersion.Factory.class);
+
+   public void testRegionUnmatchesOkWhenNoVersionIdSet() {
+      assertEquals(
+            Maps.transformValues(factory.createForApiTypeAndVersion("compute", "2").get(),
+                  Suppliers.<URI> supplierFunction()),
+            ImmutableMap.of("az-1.region-a.geo-1",
+                  URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-2.region-a.geo-1",
+                  URI.create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-3.region-a.geo-1",
+                  URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v2/3456")));
+   }
+
+   public void testRegionMatches() {
+      assertEquals(
+            Maps.transformValues(factory.createForApiTypeAndVersion("compute", "2").get(),
+                  Suppliers.<URI> supplierFunction()),
+            ImmutableMap.of("az-1.region-a.geo-1",
+                  URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-2.region-a.geo-1",
+                  URI.create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-3.region-a.geo-1",
+                  URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v2/3456")));
+   }
+
+   private final LocationIdToURIFromAccessForTypeAndVersion.Factory raxFactory = Guice.createInjector(
+         new AbstractModule() {
+
+            @Override
+            protected void configure() {
+               bindConstant().annotatedWith(Provider.class).to("rackspace");
+               bind(new TypeLiteral<Supplier<URI>>() {
+               }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
+               install(new FactoryModuleBuilder().implement(LocationIdToURIFromAccessForTypeAndVersion.class,
+                     LocationIdToURIFromAccessForTypeAndVersion.class).build(
+                     LocationIdToURIFromAccessForTypeAndVersion.Factory.class));
+               // We test against a 2.0 service catalog but it is OK for the purpose of this test
+               bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
+               }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);
+            }
+
+            @Provides
+            @Singleton
+            public Supplier<AuthInfo> provide() {
+               return Suppliers.<AuthInfo> ofInstance(new ParseRackspaceAccessTest().expected());
+            }
+         }).getInstance(LocationIdToURIFromAccessForTypeAndVersion.Factory.class);
+
+   @Test(expectedExceptions = NoSuchElementException.class)
+   public void testWhenNotInList() {
+      assertEquals(
+            Maps.transformValues(raxFactory.createForApiTypeAndVersion("goo", "1.0").get(),
+                  Suppliers.<URI> supplierFunction()),
+            ImmutableMap.of("rackspace", URI.create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
+   }
+
+   public void testProviderWhenNoRegions() {
+      Map<String, URI> withNoRegions = Maps.transformValues(raxFactory.createForApiTypeAndVersion("compute", "1.0")
+            .get(), Suppliers.<URI> supplierFunction());
+      assertEquals(withNoRegions,
+            ImmutableMap.of("rackspace", URI.create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
+   }
+
+   public void testOkWithNoVersions() {
+      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("rax:database", null).get(),
+            Suppliers.<URI> supplierFunction()), ImmutableMap.of("DFW",
+            URI.create("https://dfw.databases.api.rackspacecloud.com/v1.0/40806637803162"), "ORD",
+            URI.create("https://ord.databases.api.rackspacecloud.com/v1.0/40806637803162")));
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
new file mode 100644
index 0000000..0ed35a4
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.keystone.auth.suppliers;
+
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.inject.Singleton;
+
+import org.jclouds.location.Provider;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURISupplier;
+import org.jclouds.openstack.keystone.v2_0.catalog.V2ServiceCatalog;
+import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
+import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Provides;
+import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+
+@Test(groups = "unit", testName = "RegionIdToAdminURIFromAccessForTypeAndVersionTest")
+public class RegionIdToAdminURIFromAccessForTypeAndVersionTest {
+   private final RegionIdToAdminURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
+
+      @Override
+      protected void configure() {
+         bindConstant().annotatedWith(Provider.class).to("openstack-keystone");
+         bind(new TypeLiteral<Supplier<URI>>() {
+         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
+         install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
+                  RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
+         // We test against a 2.0 service catalog but it is OK for the purpose of this test
+         bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
+         }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);
+      }
+
+      @Provides
+      @Singleton
+      public Supplier<AuthInfo> provide() {
+         return Suppliers.<AuthInfo> ofInstance(new ParseAccessTest().expected());
+      }
+   }).getInstance(RegionIdToAdminURISupplier.Factory.class);
+
+   public void testRegionMatches() {
+      assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("identity", "2.0").get(), Suppliers
+               .<URI> supplierFunction()), ImmutableMap.of("region-a.geo-1", URI.create("https://csnode.jclouds.org:35357/v2.0/")));
+      Map<String, URI> map = Maps.newLinkedHashMap();
+      map.put("region-a.geo-1", null);
+      map.put("region-b.geo-1", null);
+      map.put("region-c.geo-1", null);
+      assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "2").get(), Suppliers
+               .<URI> supplierFunction()), map);
+   }
+   
+   private final RegionIdToAdminURISupplier.Factory raxFactory = Guice.createInjector(new AbstractModule() {
+
+      @Override
+      protected void configure() {
+         bindConstant().annotatedWith(Provider.class).to("rackspace");
+         bind(new TypeLiteral<Supplier<URI>>() {
+         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
+         install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
+                  RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
+         // We test against a 2.0 service catalog but it is OK for the purpose of this test
+         bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
+         }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);
+      }
+
+      @Provides
+      @Singleton
+      public Supplier<AuthInfo> provide() {
+         return Suppliers.<AuthInfo> ofInstance(new ParseRackspaceAccessTest().expected());
+      }
+   }).getInstance(RegionIdToAdminURISupplier.Factory.class);
+
+   @Test(expectedExceptions = NoSuchElementException.class)
+   public void testWhenNotInList() {
+      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("goo", "1.0").get(), Suppliers
+               .<URI> supplierFunction()), ImmutableMap.of("rackspace", URI
+               .create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
+   }
+   
+   public void testProviderWhenNoRegions() {
+      Map<String, URI> map = Maps.newLinkedHashMap();
+      map.put("rackspace", null);
+      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("compute", "1.0").get(), Suppliers
+               .<URI> supplierFunction()), map);
+   }
+   
+   public void testOkWithNoVersions() {
+      Map<String, URI> map = Maps.newLinkedHashMap();
+      map.put("DFW", null);
+      map.put("ORD", null);
+      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("rax:database", null).get(), Suppliers
+               .<URI> supplierFunction()), map);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
new file mode 100644
index 0000000..cbdaf21
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.keystone.auth.suppliers;
+
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import javax.inject.Singleton;
+
+import org.jclouds.location.Provider;
+import org.jclouds.location.suppliers.RegionIdToURISupplier;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.v2_0.catalog.V2ServiceCatalog;
+import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
+import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Provides;
+import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+
+@Test(groups = "unit", testName = "RegionIdToURIFromAccessForTypeAndVersionTest")
+public class RegionIdToURIFromAccessForTypeAndVersionTest {
+   private final RegionIdToURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
+
+      @Override
+      protected void configure() {
+         bindConstant().annotatedWith(Provider.class).to("openstack-keystone");
+         bind(new TypeLiteral<Supplier<URI>>() {
+         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
+         install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
+                  RegionIdToURIFromAccessForTypeAndVersion.class).build(
+                  RegionIdToURISupplier.Factory.class));
+         // We test against a 2.0 service catalog but it is OK for the purpose of this test
+         bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
+         }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);
+      }
+
+      @Provides
+      @Singleton
+      public Supplier<AuthInfo> provide() {
+         return Suppliers.<AuthInfo> ofInstance(new ParseAccessTest().expected());
+      }
+   }).getInstance(RegionIdToURISupplier.Factory.class);
+
+   @Test(expectedExceptions = NoSuchElementException.class)
+   public void testRegionUnmatches() {
+      Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.0").get(),
+               Suppliers.<URI> supplierFunction());
+   }
+   
+   public void testRegionMatches() {
+      assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "2").get(), Suppliers
+               .<URI> supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI
+               .create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-2.region-a.geo-1", URI
+               .create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-3.region-a.geo-1", URI
+               .create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v2/3456")));
+   }
+
+   private final RegionIdToURISupplier.Factory raxFactory = Guice.createInjector(new AbstractModule() {
+
+      @Override
+      protected void configure() {
+         bindConstant().annotatedWith(Provider.class).to("rackspace");
+         bind(new TypeLiteral<Supplier<URI>>() {
+         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
+         install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
+                  RegionIdToURIFromAccessForTypeAndVersion.class).build(
+                  RegionIdToURISupplier.Factory.class));
+         // We test against a 2.0 service catalog but it is OK for the purpose of this test
+         bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
+         }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);
+      }
+
+      @Provides
+      @Singleton
+      public Supplier<AuthInfo> provide() {
+         return Suppliers.<AuthInfo> ofInstance(new ParseRackspaceAccessTest().expected());
+      }
+   }).getInstance(RegionIdToURISupplier.Factory.class);
+
+   @Test(expectedExceptions = NoSuchElementException.class)
+   public void testWhenNotInList() {
+      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("goo", "1.0").get(), Suppliers
+               .<URI> supplierFunction()), ImmutableMap.of("rackspace", URI
+               .create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
+   }
+
+   public void testProviderWhenNoRegions() {
+      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("compute", "1.0").get(), Suppliers
+               .<URI> supplierFunction()), ImmutableMap.of("rackspace", URI
+               .create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
+   }
+
+   public void testOkWithNoVersions() {
+      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("rax:database", null).get(), Suppliers
+               .<URI> supplierFunction()), ImmutableMap.of("DFW", URI
+               .create("https://dfw.databases.api.rackspacecloud.com/v1.0/40806637803162"), "ORD", URI
+               .create("https://ord.databases.api.rackspacecloud.com/v1.0/40806637803162")));
+   }
+
+}


[8/8] jclouds git commit: fix for keystone v3 liveTests (#1)

Posted by na...@apache.org.
fix for keystone v3 liveTests (#1)

- some minor renaming for even better clarity

Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/17c11ec9
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/17c11ec9
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/17c11ec9

Branch: refs/heads/keystonev3
Commit: 17c11ec9d7c24bda5845dac77f5b284e7364148f
Parents: 7def816
Author: Andrea Turli <an...@users.noreply.github.com>
Authored: Fri Dec 8 13:55:20 2017 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Fri Dec 8 13:55:20 2017 +0100

----------------------------------------------------------------------
 .../auth/config/AuthenticationModule.java       |   6 +-
 .../auth/domain/ApiAccessKeyCredentials.java    |   2 +-
 .../auth/domain/PasswordCredentials.java        |   2 +-
 .../keystone/auth/domain/TokenCredentials.java  |   2 +-
 .../keystone/catalog/ServiceEndpoint.java       |   4 +-
 .../catalog/config/KeystoneAdminURLModule.java  |   4 +-
 .../catalog/config/ServiceCatalogModule.java    |  14 +-
 ...ationIdToURIFromAccessForTypeAndVersion.java | 129 -------------------
 ...RIFromServiceEndpointsForTypeAndVersion.java | 129 +++++++++++++++++++
 ...IdToAdminURIFromAccessForTypeAndVersion.java |  44 -------
 ...RIFromServiceEndpointsForTypeAndVersion.java |  44 +++++++
 .../suppliers/RegionIdToAdminURISupplier.java   |   2 +-
 ...egionIdToURIFromAccessForTypeAndVersion.java |  46 -------
 ...RIFromServiceEndpointsForTypeAndVersion.java |  46 +++++++
 .../keystone/v3/auth/V3AuthenticationApi.java   |   6 +-
 .../openstack/keystone/v3/domain/Auth.java      |   2 +-
 .../keystone/v3/parsers/ParseToken.java         |  41 ------
 .../v3/parsers/ParseTokenFromHttpResponse.java  |  50 +++++++
 ...nIdToURIFromAccessForTypeAndVersionTest.java |  22 ++--
 ...AdminURIFromAccessForTypeAndVersionTest.java |   6 +-
 ...nIdToURIFromAccessForTypeAndVersionTest.java |   6 +-
 21 files changed, 308 insertions(+), 299 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/AuthenticationModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/AuthenticationModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/AuthenticationModule.java
index dbd9743..6731fe8 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/AuthenticationModule.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/AuthenticationModule.java
@@ -99,7 +99,7 @@ public class AuthenticationModule extends AbstractModule {
    }
 
    protected Map<String, Function<Credentials, AuthInfo>> authenticationMethods(Injector i) {
-      Builder<Function<Credentials, AuthInfo>> fns = ImmutableSet.<Function<Credentials, AuthInfo>> builder();
+      Builder<Function<Credentials, AuthInfo>> fns = ImmutableSet.builder();
       fns.add(i.getInstance(AuthenticatePasswordCredentials.class));
       fns.add(i.getInstance(AuthenticateApiAccessKeyCredentials.class));
       fns.add(i.getInstance(AuthenticateTokenCredentials.class));
@@ -121,7 +121,7 @@ public class AuthenticationModule extends AbstractModule {
    // at 11 hours for now.
    @Provides
    @Singleton
-   public final LoadingCache<Credentials, AuthInfo> provideAccessCache(Function<Credentials, AuthInfo> getAccess) {
+   public final LoadingCache<Credentials, AuthInfo> provideAuthInfoCache(Function<Credentials, AuthInfo> getAccess) {
       return CacheBuilder.newBuilder().expireAfterWrite(11, TimeUnit.HOURS).build(CacheLoader.from(getAccess));
    }
 
@@ -130,7 +130,7 @@ public class AuthenticationModule extends AbstractModule {
    // http://code.google.com/p/guava-libraries/issues/detail?id=872
    @Provides
    @Singleton
-   protected final Supplier<AuthInfo> provideAccessSupplier(final LoadingCache<Credentials, AuthInfo> cache,
+   protected final Supplier<AuthInfo> provideAuthInfoSupplier(final LoadingCache<Credentials, AuthInfo> cache,
          @Provider final Supplier<Credentials> creds) {
       return new Supplier<AuthInfo>() {
          @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/ApiAccessKeyCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/ApiAccessKeyCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/ApiAccessKeyCredentials.java
index c2e1e47..75ccf88 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/ApiAccessKeyCredentials.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/ApiAccessKeyCredentials.java
@@ -29,7 +29,7 @@ public abstract class ApiAccessKeyCredentials {
    public abstract String accessKey();
    public abstract String secretKey();
 
-   public static ApiAccessKeyCredentials create(String accessKey, String secretKey, String tenantId, String tenantName) {
+   public static ApiAccessKeyCredentials create(String accessKey, String secretKey) {
       return builder().accessKey(accessKey).secretKey(secretKey).build();
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/PasswordCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/PasswordCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/PasswordCredentials.java
index d7a039c..2e1fee9 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/PasswordCredentials.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/PasswordCredentials.java
@@ -30,7 +30,7 @@ public abstract class PasswordCredentials {
    public abstract String username();
    public abstract String password();
 
-   public static PasswordCredentials create(String username, String password, String tenantId, String tenantName) {
+   public static PasswordCredentials create(String username, String password) {
       return builder().username(username).password(password).build();
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TokenCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TokenCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TokenCredentials.java
index 7a4e0d3..7f5d0b2 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TokenCredentials.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TokenCredentials.java
@@ -28,7 +28,7 @@ public abstract class TokenCredentials {
 
    public abstract String id();
 
-   public static TokenCredentials create(String id, String secretKey, String tenantId, String tenantName) {
+   public static TokenCredentials create(String id) {
       return builder().id(id).build();
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/ServiceEndpoint.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/ServiceEndpoint.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/ServiceEndpoint.java
index 139751e..08477c0 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/ServiceEndpoint.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/ServiceEndpoint.java
@@ -32,11 +32,11 @@ import com.google.common.base.Enums;
 @AutoValue
 public abstract class ServiceEndpoint {
 
-   public static enum Interface {
+   public enum Interface {
       PUBLIC, ADMIN, INTERNAL, UNRECOGNIZED;
 
       public static Interface fromValue(String iface) {
-         return Enums.getIfPresent(Interface.class, iface.toLowerCase()).or(UNRECOGNIZED);
+         return Enums.getIfPresent(Interface.class, iface.toUpperCase()).or(UNRECOGNIZED);
       }
    }
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/KeystoneAdminURLModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/KeystoneAdminURLModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/KeystoneAdminURLModule.java
index d670973..6f357c0 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/KeystoneAdminURLModule.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/KeystoneAdminURLModule.java
@@ -24,7 +24,7 @@ import java.util.NoSuchElementException;
 import javax.inject.Singleton;
 
 import org.jclouds.location.Provider;
-import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion;
 import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURISupplier;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Identity;
@@ -41,7 +41,7 @@ public class KeystoneAdminURLModule extends AbstractModule {
    @Override
    protected void configure() {
       install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
-               RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
+               RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
    }
 
    /**

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/ServiceCatalogModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/ServiceCatalogModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/ServiceCatalogModule.java
index 9761da0..9019c7c 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/ServiceCatalogModule.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/ServiceCatalogModule.java
@@ -34,10 +34,10 @@ import org.jclouds.location.suppliers.all.RegionToProvider;
 import org.jclouds.location.suppliers.derived.RegionIdsFromRegionIdToURIKeySet;
 import org.jclouds.location.suppliers.implicit.FirstRegion;
 import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
-import org.jclouds.openstack.keystone.catalog.suppliers.LocationIdToURIFromAccessForTypeAndVersion;
-import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.LocationIdToURIFromServiceEndpointsForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion;
 import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURISupplier;
-import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToURIFromServiceEndpointsForTypeAndVersion;
 import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.openstack.keystone.v2_0.catalog.V2ServiceCatalog;
 import org.jclouds.openstack.keystone.v3.catalog.V3ServiceCatalog;
@@ -88,14 +88,14 @@ public class ServiceCatalogModule extends AbstractModule {
    public static class ProviderModule extends AbstractModule {
       @Override
       protected void configure() {
-         install(new FactoryModuleBuilder().build(LocationIdToURIFromAccessForTypeAndVersion.Factory.class));
+         install(new FactoryModuleBuilder().build(LocationIdToURIFromServiceEndpointsForTypeAndVersion.Factory.class));
       }
 
       @Provides
       @Singleton
       protected final Supplier<URI> provideZoneIdToURISupplierForApiVersion(
             @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
-            LocationIdToURIFromAccessForTypeAndVersion.Factory factory) {
+            LocationIdToURIFromServiceEndpointsForTypeAndVersion.Factory factory) {
          return getLastValueInMap(factory.createForApiTypeAndVersion(serviceType, apiVersion));
       }
 
@@ -115,9 +115,9 @@ public class ServiceCatalogModule extends AbstractModule {
       @Override
       protected void configure() {
          install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
-               RegionIdToURIFromAccessForTypeAndVersion.class).build(RegionIdToURISupplier.Factory.class));
+               RegionIdToURIFromServiceEndpointsForTypeAndVersion.class).build(RegionIdToURISupplier.Factory.class));
          install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
-               RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
+               RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
          // Dynamically build the region list as opposed to from properties
          bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class);
          bind(ImplicitLocationSupplier.class).to(FirstRegion.class).in(Scopes.SINGLETON);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java
deleted file mode 100644
index 8adf561..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java
+++ /dev/null
@@ -1,129 +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.keystone.catalog.suppliers;
-
-import static com.google.common.collect.Iterables.any;
-import static com.google.common.collect.Iterables.filter;
-import static com.google.common.collect.Iterables.isEmpty;
-import static com.google.common.collect.Maps.transformValues;
-import static com.google.common.collect.Multimaps.asMap;
-import static com.google.common.collect.Multimaps.index;
-
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.annotation.Resource;
-
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.logging.Logger;
-import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
-import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointResolutionStrategy;
-import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointToRegion;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.collect.Multimap;
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-
-public class LocationIdToURIFromAccessForTypeAndVersion implements Supplier<Map<String, Supplier<URI>>> {
-
-   public interface Factory {
-      
-      LocationIdToURIFromAccessForTypeAndVersion createForApiTypeAndVersion(@Assisted("apiType") String apiType,
-            @Nullable @Assisted("apiVersion") String apiVersion) throws NoSuchElementException;
-   }
-
-   @Resource
-   protected Logger logger = Logger.NULL;
-
-   protected final Supplier<List<ServiceEndpoint>> serviceEndpoints;
-   protected final ServiceEndpointResolutionStrategy resolveServiceEndpointURI;
-   protected final ServiceEndpointToRegion serviceEndpointToRegion;
-   protected final String apiType;
-   protected final String apiVersion;
-
-   @Inject
-   LocationIdToURIFromAccessForTypeAndVersion(Supplier<List<ServiceEndpoint>> serviceEndpoints,
-         ServiceEndpointResolutionStrategy resolveServiceEndpointURI, ServiceEndpointToRegion serviceEndpointToRegion,
-         @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
-      this.serviceEndpoints = serviceEndpoints;
-      this.resolveServiceEndpointURI = resolveServiceEndpointURI;
-      this.serviceEndpointToRegion = serviceEndpointToRegion;
-      this.apiType = apiType;
-      this.apiVersion = apiVersion;
-   }
-
-   @Override
-   public Map<String, Supplier<URI>> get() {
-      List<ServiceEndpoint> endpoints = serviceEndpoints.get();
-
-      // Filter endpoints by service type
-      Iterable<ServiceEndpoint> endpointsForType = filter(endpoints, apiTypeEquals);
-      if (isEmpty(endpointsForType)) {
-         throw new NoSuchElementException(String.format("no endpoints for apiType %s in service endpoints %s", apiType,
-               endpoints));
-      }
-      
-      // Check if there are endpoints for a particular version, if specified and
-      // there are versioned endpoints
-      boolean checkVersionId = apiVersion != null && any(endpointsForType, versionAware);
-      Predicate<ServiceEndpoint> versionFilter = checkVersionId ? apiVersionEqualsVersionId : Predicates.<ServiceEndpoint> alwaysTrue();
-      Iterable<ServiceEndpoint> endpointsForTypeAndVersion = filter(endpointsForType, versionFilter);
-      if (isEmpty(endpointsForTypeAndVersion)) {
-         throw new NoSuchElementException(String.format(
-               "no service endpoints for apiType %s are of version %s, or version agnostic: %s", apiType, apiVersion,
-               endpointsForType));
-      }
-
-      logger.debug("service endpoints for apiType %s and version %s: %s", apiType, apiVersion,
-            endpointsForTypeAndVersion);
-      
-      Multimap<String, ServiceEndpoint> locationToServiceEndpoints = index(endpointsForTypeAndVersion,
-            serviceEndpointToRegion);
-      return transformValues(asMap(locationToServiceEndpoints), resolveServiceEndpointURI);
-   }
-
-   private final Predicate<ServiceEndpoint> apiVersionEqualsVersionId = new Predicate<ServiceEndpoint>() {
-      @Override
-      public boolean apply(ServiceEndpoint input) {
-         return input.version().equals(apiVersion);
-      }
-   };
-
-   private final Predicate<ServiceEndpoint> versionAware = new Predicate<ServiceEndpoint>() {
-      @Override
-      public boolean apply(ServiceEndpoint input) {
-         return input.version() != null;
-      }
-   };
-
-   private final Predicate<ServiceEndpoint> apiTypeEquals = new Predicate<ServiceEndpoint>() {
-      @Override
-      public boolean apply(ServiceEndpoint input) {
-         return input.type().equals(apiType);
-      }
-   };
-
-   @Override
-   public String toString() {
-      return "locationIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromServiceEndpointsForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromServiceEndpointsForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromServiceEndpointsForTypeAndVersion.java
new file mode 100644
index 0000000..a96503d
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/LocationIdToURIFromServiceEndpointsForTypeAndVersion.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.keystone.catalog.suppliers;
+
+import static com.google.common.collect.Iterables.any;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.isEmpty;
+import static com.google.common.collect.Maps.transformValues;
+import static com.google.common.collect.Multimaps.asMap;
+import static com.google.common.collect.Multimaps.index;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.annotation.Resource;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointResolutionStrategy;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointToRegion;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Multimap;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+
+public class LocationIdToURIFromServiceEndpointsForTypeAndVersion implements Supplier<Map<String, Supplier<URI>>> {
+
+   public interface Factory {
+      
+      LocationIdToURIFromServiceEndpointsForTypeAndVersion createForApiTypeAndVersion(@Assisted("apiType") String apiType,
+                                                                                      @Nullable @Assisted("apiVersion") String apiVersion) throws NoSuchElementException;
+   }
+
+   @Resource
+   protected Logger logger = Logger.NULL;
+
+   protected final Supplier<List<ServiceEndpoint>> serviceEndpoints;
+   protected final ServiceEndpointResolutionStrategy resolveServiceEndpointURI;
+   protected final ServiceEndpointToRegion serviceEndpointToRegion;
+   protected final String apiType;
+   protected final String apiVersion;
+
+   @Inject
+   LocationIdToURIFromServiceEndpointsForTypeAndVersion(Supplier<List<ServiceEndpoint>> serviceEndpoints,
+                                                        ServiceEndpointResolutionStrategy resolveServiceEndpointURI, ServiceEndpointToRegion serviceEndpointToRegion,
+                                                        @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
+      this.serviceEndpoints = serviceEndpoints;
+      this.resolveServiceEndpointURI = resolveServiceEndpointURI;
+      this.serviceEndpointToRegion = serviceEndpointToRegion;
+      this.apiType = apiType;
+      this.apiVersion = apiVersion;
+   }
+
+   @Override
+   public Map<String, Supplier<URI>> get() {
+      List<ServiceEndpoint> endpoints = serviceEndpoints.get();
+
+      // Filter endpoints by service type
+      Iterable<ServiceEndpoint> endpointsForType = filter(endpoints, apiTypeEquals);
+      if (isEmpty(endpointsForType)) {
+         throw new NoSuchElementException(String.format("no endpoints for apiType %s in service endpoints %s", apiType,
+               endpoints));
+      }
+      
+      // Check if there are endpoints for a particular version, if specified and
+      // there are versioned endpoints
+      boolean checkVersionId = apiVersion != null && any(endpointsForType, versionAware);
+      Predicate<ServiceEndpoint> versionFilter = checkVersionId ? apiVersionEqualsVersionId : Predicates.<ServiceEndpoint> alwaysTrue();
+      Iterable<ServiceEndpoint> endpointsForTypeAndVersion = filter(endpointsForType, versionFilter);
+      if (isEmpty(endpointsForTypeAndVersion)) {
+         throw new NoSuchElementException(String.format(
+               "no service endpoints for apiType %s are of version %s, or version agnostic: %s", apiType, apiVersion,
+               endpointsForType));
+      }
+
+      logger.debug("service endpoints for apiType %s and version %s: %s", apiType, apiVersion,
+            endpointsForTypeAndVersion);
+      
+      Multimap<String, ServiceEndpoint> locationToServiceEndpoints = index(endpointsForTypeAndVersion,
+            serviceEndpointToRegion);
+      return transformValues(asMap(locationToServiceEndpoints), resolveServiceEndpointURI);
+   }
+
+   private final Predicate<ServiceEndpoint> apiVersionEqualsVersionId = new Predicate<ServiceEndpoint>() {
+      @Override
+      public boolean apply(ServiceEndpoint input) {
+         return input.version().equals(apiVersion);
+      }
+   };
+
+   private final Predicate<ServiceEndpoint> versionAware = new Predicate<ServiceEndpoint>() {
+      @Override
+      public boolean apply(ServiceEndpoint input) {
+         return input.version() != null;
+      }
+   };
+
+   private final Predicate<ServiceEndpoint> apiTypeEquals = new Predicate<ServiceEndpoint>() {
+      @Override
+      public boolean apply(ServiceEndpoint input) {
+         return input.type().equals(apiType);
+      }
+   };
+
+   @Override
+   public String toString() {
+      return "locationIdToURIFromServiceEndpointsForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java
deleted file mode 100644
index 740b7a3..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java
+++ /dev/null
@@ -1,44 +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.keystone.catalog.suppliers;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
-import org.jclouds.openstack.keystone.catalog.functions.AdminEndpointResolutionStrategy;
-import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointToRegion;
-
-import com.google.common.base.Supplier;
-import com.google.inject.assistedinject.Assisted;
-
-public class RegionIdToAdminURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
-      RegionIdToAdminURISupplier {
-   @Inject
-   public RegionIdToAdminURIFromAccessForTypeAndVersion(Supplier<List<ServiceEndpoint>> serviceEndpoints,
-         AdminEndpointResolutionStrategy resolveServiceEndpointURI, ServiceEndpointToRegion serviceEndpointToRegion,
-         @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
-      super(serviceEndpoints, resolveServiceEndpointURI, serviceEndpointToRegion, apiType, apiVersion);
-   }
-
-   @Override
-   public String toString() {
-      return "regionIdToAdminURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion.java
new file mode 100644
index 0000000..742d440
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion.java
@@ -0,0 +1,44 @@
+/*
+ * 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.keystone.catalog.suppliers;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.functions.AdminEndpointResolutionStrategy;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointToRegion;
+
+import com.google.common.base.Supplier;
+import com.google.inject.assistedinject.Assisted;
+
+public class RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion extends LocationIdToURIFromServiceEndpointsForTypeAndVersion implements
+      RegionIdToAdminURISupplier {
+   @Inject
+   public RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion(Supplier<List<ServiceEndpoint>> serviceEndpoints,
+                                                                  AdminEndpointResolutionStrategy resolveServiceEndpointURI, ServiceEndpointToRegion serviceEndpointToRegion,
+                                                                  @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
+      super(serviceEndpoints, resolveServiceEndpointURI, serviceEndpointToRegion, apiType, apiVersion);
+   }
+
+   @Override
+   public String toString() {
+      return "regionIdToAdminURIFromServiceEndpointsForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURISupplier.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURISupplier.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURISupplier.java
index 0f70205..07f1773 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURISupplier.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToAdminURISupplier.java
@@ -26,7 +26,7 @@ import com.google.common.base.Supplier;
 import com.google.inject.ImplementedBy;
 import com.google.inject.assistedinject.Assisted;
 
-@ImplementedBy(RegionIdToAdminURIFromAccessForTypeAndVersion.class)
+@ImplementedBy(RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion.class)
 public interface RegionIdToAdminURISupplier extends Supplier<Map<String, Supplier<URI>>> {
 
    interface Factory {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java
deleted file mode 100644
index d40b4af..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java
+++ /dev/null
@@ -1,46 +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.keystone.catalog.suppliers;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.location.suppliers.RegionIdToURISupplier;
-import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
-import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointResolutionStrategy;
-import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointToRegion;
-
-import com.google.common.base.Supplier;
-import com.google.inject.assistedinject.Assisted;
-
-public class RegionIdToURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
-      RegionIdToURISupplier {
-
-   @Inject
-   public RegionIdToURIFromAccessForTypeAndVersion(Supplier<List<ServiceEndpoint>> serviceEndpoints,
-         ServiceEndpointResolutionStrategy resolveServiceEndpointURI, ServiceEndpointToRegion serviceEndpointToRegion,
-         @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
-      super(serviceEndpoints, resolveServiceEndpointURI, serviceEndpointToRegion, apiType, apiVersion);
-   }
-
-   @Override
-   public String toString() {
-      return "regionIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromServiceEndpointsForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromServiceEndpointsForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromServiceEndpointsForTypeAndVersion.java
new file mode 100644
index 0000000..7065ee5
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/suppliers/RegionIdToURIFromServiceEndpointsForTypeAndVersion.java
@@ -0,0 +1,46 @@
+/*
+ * 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.keystone.catalog.suppliers;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.suppliers.RegionIdToURISupplier;
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointResolutionStrategy;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointToRegion;
+
+import com.google.common.base.Supplier;
+import com.google.inject.assistedinject.Assisted;
+
+public class RegionIdToURIFromServiceEndpointsForTypeAndVersion extends LocationIdToURIFromServiceEndpointsForTypeAndVersion implements
+      RegionIdToURISupplier {
+
+   @Inject
+   public RegionIdToURIFromServiceEndpointsForTypeAndVersion(Supplier<List<ServiceEndpoint>> serviceEndpoints,
+                                                             ServiceEndpointResolutionStrategy resolveServiceEndpointURI, ServiceEndpointToRegion serviceEndpointToRegion,
+                                                             @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
+      super(serviceEndpoints, resolveServiceEndpointURI, serviceEndpointToRegion, apiType, apiVersion);
+   }
+
+   @Override
+   public String toString() {
+      return "regionIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/auth/V3AuthenticationApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/auth/V3AuthenticationApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/auth/V3AuthenticationApi.java
index 7a84c21..0553c15 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/auth/V3AuthenticationApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/auth/V3AuthenticationApi.java
@@ -30,7 +30,7 @@ import org.jclouds.openstack.keystone.auth.domain.TokenCredentials;
 import org.jclouds.openstack.keystone.v3.binders.BindPasswordAuthToJsonPayload;
 import org.jclouds.openstack.keystone.v3.binders.BindTokenAuthToJsonPayload;
 import org.jclouds.openstack.keystone.v3.domain.Token;
-import org.jclouds.openstack.keystone.v3.parsers.ParseToken;
+import org.jclouds.openstack.keystone.v3.parsers.ParseTokenFromHttpResponse;
 import org.jclouds.rest.annotations.MapBinder;
 import org.jclouds.rest.annotations.ResponseParser;
 
@@ -45,14 +45,14 @@ public interface V3AuthenticationApi extends AuthenticationApi, Closeable {
 
    @Named("token:create")
    @POST
-   @ResponseParser(ParseToken.class)
+   @ResponseParser(ParseTokenFromHttpResponse.class) //ParseToken.class)
    @MapBinder(BindPasswordAuthToJsonPayload.class)
    @Override
    Token authenticatePassword(TenantAndCredentials<PasswordCredentials> credentials);
 
    @Named("token:create")
    @POST
-   @ResponseParser(ParseToken.class)
+   @ResponseParser(ParseTokenFromHttpResponse.class) //ParseToken.class)
    @MapBinder(BindTokenAuthToJsonPayload.class)
    @Override
    Token authenticateToken(TenantAndCredentials<TokenCredentials> credentials);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Auth.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Auth.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Auth.java
index 13c3753..fb2caf5 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Auth.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/domain/Auth.java
@@ -37,7 +37,7 @@ public abstract class Auth {
    public abstract static class Identity {
       
       public abstract List<String> methods();
-      public abstract TokenAuth token();
+      @Nullable public abstract TokenAuth token();
       public abstract PasswordAuth password();
 
       @SerializedNames({ "methods", "token", "password" })

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseToken.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseToken.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseToken.java
deleted file mode 100644
index 1fd633f..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseToken.java
+++ /dev/null
@@ -1,41 +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.keystone.v3.parsers;
-
-import org.jclouds.http.HttpResponse;
-import org.jclouds.http.functions.ParseFirstJsonValueNamed;
-import org.jclouds.json.internal.GsonWrapper;
-import org.jclouds.openstack.keystone.v3.domain.Token;
-
-import com.google.common.collect.Iterables;
-import com.google.inject.Inject;
-import com.google.inject.TypeLiteral;
-
-public class ParseToken extends ParseFirstJsonValueNamed<Token> {
-
-   @Inject
-   ParseToken(GsonWrapper json, TypeLiteral<Token> type, String... nameChoices) {
-      super(json, type, nameChoices);
-   }
-
-   @Override
-   public Token apply(HttpResponse from) {
-      Token token = super.apply(from);
-      String xSubjectToken = Iterables.getOnlyElement(from.getHeaders().get("X-Subject-Token"));
-      return token.toBuilder().id(xSubjectToken).build();
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseTokenFromHttpResponse.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseTokenFromHttpResponse.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseTokenFromHttpResponse.java
new file mode 100644
index 0000000..9a5b799
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/parsers/ParseTokenFromHttpResponse.java
@@ -0,0 +1,50 @@
+/*
+ * 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.keystone.v3.parsers;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.inject.Singleton;
+
+import com.google.common.collect.Iterables;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.functions.ParseFirstJsonValueNamed;
+import org.jclouds.json.internal.GsonWrapper;
+import org.jclouds.openstack.keystone.v3.domain.Token;
+
+import com.google.common.base.Function;
+import com.google.inject.Inject;
+import com.google.inject.TypeLiteral;
+
+@Singleton
+public class ParseTokenFromHttpResponse implements Function<HttpResponse, Token> {
+   private final ParseFirstJsonValueNamed<Token> parser;
+
+   @Inject
+   public ParseTokenFromHttpResponse(GsonWrapper gsonView) {
+      this.parser = new ParseFirstJsonValueNamed<Token>(gsonView, TypeLiteral.get(Token.class), "token");
+   }
+
+   public Token apply(HttpResponse response) {
+      checkNotNull(response, "response");
+      Token toParse = parser.apply(response);
+      checkNotNull(toParse, "parsed result from %s", response);
+      String xSubjectToken = Iterables.getOnlyElement(response.getHeaders().get("X-Subject-Token"));
+      return toParse.toBuilder().id(xSubjectToken).build();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
index 91146b0..0b1c890 100644
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
@@ -28,7 +28,7 @@ import javax.inject.Singleton;
 import org.jclouds.location.Provider;
 import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
 import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
-import org.jclouds.openstack.keystone.catalog.suppliers.LocationIdToURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.LocationIdToURIFromServiceEndpointsForTypeAndVersion;
 import org.jclouds.openstack.keystone.v2_0.catalog.V2ServiceCatalog;
 import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
 import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
@@ -47,7 +47,7 @@ import com.google.inject.assistedinject.FactoryModuleBuilder;
 
 @Test(groups = "unit", testName = "LocationIdToURIFromAccessForTypeAndVersionTest")
 public class LocationIdToURIFromAccessForTypeAndVersionTest {
-   private final LocationIdToURIFromAccessForTypeAndVersion.Factory factory = Guice.createInjector(
+   private final LocationIdToURIFromServiceEndpointsForTypeAndVersion.Factory factory = Guice.createInjector(
          new AbstractModule() {
 
             @Override
@@ -55,9 +55,9 @@ public class LocationIdToURIFromAccessForTypeAndVersionTest {
                bindConstant().annotatedWith(Provider.class).to("openstack-keystone");
                bind(new TypeLiteral<Supplier<URI>>() {
                }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
-               install(new FactoryModuleBuilder().implement(LocationIdToURIFromAccessForTypeAndVersion.class,
-                     LocationIdToURIFromAccessForTypeAndVersion.class).build(
-                     LocationIdToURIFromAccessForTypeAndVersion.Factory.class));
+               install(new FactoryModuleBuilder().implement(LocationIdToURIFromServiceEndpointsForTypeAndVersion.class,
+                     LocationIdToURIFromServiceEndpointsForTypeAndVersion.class).build(
+                     LocationIdToURIFromServiceEndpointsForTypeAndVersion.Factory.class));
                // We test against a 2.0 service catalog but it is OK for the purpose of this test
                bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
                }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);
@@ -69,7 +69,7 @@ public class LocationIdToURIFromAccessForTypeAndVersionTest {
                return Suppliers.<AuthInfo> ofInstance(new ParseAccessTest().expected());
             }
 
-         }).getInstance(LocationIdToURIFromAccessForTypeAndVersion.Factory.class);
+         }).getInstance(LocationIdToURIFromServiceEndpointsForTypeAndVersion.Factory.class);
 
    public void testRegionUnmatchesOkWhenNoVersionIdSet() {
       assertEquals(
@@ -91,7 +91,7 @@ public class LocationIdToURIFromAccessForTypeAndVersionTest {
                   URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v2/3456")));
    }
 
-   private final LocationIdToURIFromAccessForTypeAndVersion.Factory raxFactory = Guice.createInjector(
+   private final LocationIdToURIFromServiceEndpointsForTypeAndVersion.Factory raxFactory = Guice.createInjector(
          new AbstractModule() {
 
             @Override
@@ -99,9 +99,9 @@ public class LocationIdToURIFromAccessForTypeAndVersionTest {
                bindConstant().annotatedWith(Provider.class).to("rackspace");
                bind(new TypeLiteral<Supplier<URI>>() {
                }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
-               install(new FactoryModuleBuilder().implement(LocationIdToURIFromAccessForTypeAndVersion.class,
-                     LocationIdToURIFromAccessForTypeAndVersion.class).build(
-                     LocationIdToURIFromAccessForTypeAndVersion.Factory.class));
+               install(new FactoryModuleBuilder().implement(LocationIdToURIFromServiceEndpointsForTypeAndVersion.class,
+                     LocationIdToURIFromServiceEndpointsForTypeAndVersion.class).build(
+                     LocationIdToURIFromServiceEndpointsForTypeAndVersion.Factory.class));
                // We test against a 2.0 service catalog but it is OK for the purpose of this test
                bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
                }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);
@@ -112,7 +112,7 @@ public class LocationIdToURIFromAccessForTypeAndVersionTest {
             public Supplier<AuthInfo> provide() {
                return Suppliers.<AuthInfo> ofInstance(new ParseRackspaceAccessTest().expected());
             }
-         }).getInstance(LocationIdToURIFromAccessForTypeAndVersion.Factory.class);
+         }).getInstance(LocationIdToURIFromServiceEndpointsForTypeAndVersion.Factory.class);
 
    @Test(expectedExceptions = NoSuchElementException.class)
    public void testWhenNotInList() {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
index 0ed35a4..3a632e2 100644
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
@@ -28,7 +28,7 @@ import javax.inject.Singleton;
 import org.jclouds.location.Provider;
 import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
 import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
-import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion;
 import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURISupplier;
 import org.jclouds.openstack.keystone.v2_0.catalog.V2ServiceCatalog;
 import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
@@ -56,7 +56,7 @@ public class RegionIdToAdminURIFromAccessForTypeAndVersionTest {
          bind(new TypeLiteral<Supplier<URI>>() {
          }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
          install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
-                  RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
+                  RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
          // We test against a 2.0 service catalog but it is OK for the purpose of this test
          bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
          }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);
@@ -88,7 +88,7 @@ public class RegionIdToAdminURIFromAccessForTypeAndVersionTest {
          bind(new TypeLiteral<Supplier<URI>>() {
          }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
          install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
-                  RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
+                  RegionIdToAdminURIFromServiceEndpointsForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
          // We test against a 2.0 service catalog but it is OK for the purpose of this test
          bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
          }).to(V2ServiceCatalog.class).in(Scopes.SINGLETON);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/17c11ec9/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
index cbdaf21..65b820d 100644
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/auth/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
@@ -28,7 +28,7 @@ import org.jclouds.location.Provider;
 import org.jclouds.location.suppliers.RegionIdToURISupplier;
 import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
 import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
-import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToURIFromServiceEndpointsForTypeAndVersion;
 import org.jclouds.openstack.keystone.v2_0.catalog.V2ServiceCatalog;
 import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
 import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
@@ -55,7 +55,7 @@ public class RegionIdToURIFromAccessForTypeAndVersionTest {
          bind(new TypeLiteral<Supplier<URI>>() {
          }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
          install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
-                  RegionIdToURIFromAccessForTypeAndVersion.class).build(
+                  RegionIdToURIFromServiceEndpointsForTypeAndVersion.class).build(
                   RegionIdToURISupplier.Factory.class));
          // We test against a 2.0 service catalog but it is OK for the purpose of this test
          bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {
@@ -91,7 +91,7 @@ public class RegionIdToURIFromAccessForTypeAndVersionTest {
          bind(new TypeLiteral<Supplier<URI>>() {
          }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
          install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
-                  RegionIdToURIFromAccessForTypeAndVersion.class).build(
+                  RegionIdToURIFromServiceEndpointsForTypeAndVersion.class).build(
                   RegionIdToURISupplier.Factory.class));
          // We test against a 2.0 service catalog but it is OK for the purpose of this test
          bind(new TypeLiteral<Supplier<List<ServiceEndpoint>>>() {


[3/8] jclouds git commit: Initial work towards Keystone V3 authentication

Posted by na...@apache.org.
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/AdminURLTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/AdminURLTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/AdminURLTest.java
new file mode 100644
index 0000000..ed5280e
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/AdminURLTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.ADMIN;
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.PUBLIC;
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.Collections;
+
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "AdminURLTest")
+public class AdminURLTest {
+   private final AdminURL fn = new AdminURL();
+
+   public void testAdminURL() {
+      assertEquals(
+            fn.apply(
+                  Collections.singletonList(ServiceEndpoint
+                        .builder()
+                        .type("cdn")
+                        .regionId("LON")
+                        .version("1.0")
+                        .url(URI
+                              .create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
+                        .iface(ADMIN).build())).get(),
+            URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"));
+   }
+
+   public void testReturnsNullIfNotAdminURI() {
+      assertEquals(
+            fn.apply(
+                  Collections.singletonList(ServiceEndpoint.builder().type("cdn").regionId("LON").version("1.0")
+                        .url(URI.create("https://192.168.1.1")).iface(PUBLIC).build())).get(), null);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/InternalURLTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/InternalURLTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/InternalURLTest.java
new file mode 100644
index 0000000..fec5dd8
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/InternalURLTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.INTERNAL;
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.Collections;
+
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.testng.annotations.Test;
+
+/**
+ */
+@Test(groups = "unit", testName = "InternalURLTest")
+public class InternalURLTest {
+   private final InternalURL fn = new InternalURL();
+
+   public void testInternalURL() {
+      assertEquals(
+            fn.apply(Collections.singletonList(ServiceEndpoint.builder().type("cdn").regionId("regionOne")
+                  .version("2.0")
+                  .url(URI.create("https://ericsson.com/v2/1900e98b-7272-4cbd-8e95-0b8c2a9266c0"))
+                  .iface(INTERNAL).build())).get(),
+            URI.create("https://ericsson.com/v2/1900e98b-7272-4cbd-8e95-0b8c2a9266c0"));
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/PublicURLOrInternalTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/PublicURLOrInternalTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/PublicURLOrInternalTest.java
new file mode 100644
index 0000000..477236b
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/PublicURLOrInternalTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.INTERNAL;
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.PUBLIC;
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.Collections;
+
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "PublicURLOrInternalTest")
+public class PublicURLOrInternalTest {
+   private final PublicURLOrInternal fn = new PublicURLOrInternal();
+
+   public void testPublicURLNotNullReturnsPublicURL() {
+      assertEquals(
+            fn.apply(
+                  Collections.singletonList(ServiceEndpoint
+                        .builder()
+                        .type("cdn")
+                        .regionId("LON")
+                        .version("1.0")
+                        .url(URI
+                              .create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
+                        .iface(PUBLIC).build())).get(),
+            URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"));
+   }
+
+   public void testPublicURLNullReturnsInternalURL() {
+      assertEquals(
+            fn.apply(
+                  Collections.singletonList(ServiceEndpoint.builder().type("cdn").regionId("LON").version("1.0")
+                        .url(URI.create("https://192.168.1.1")).iface(INTERNAL).build())).get(),
+            URI.create("https://192.168.1.1"));
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/ReturnRegionOrProviderTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/ReturnRegionOrProviderTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/ReturnRegionOrProviderTest.java
new file mode 100644
index 0000000..bc25ad3
--- /dev/null
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/catalog/functions/ReturnRegionOrProviderTest.java
@@ -0,0 +1,45 @@
+/*
+ * 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.keystone.catalog.functions;
+
+import static org.jclouds.openstack.keystone.catalog.ServiceEndpoint.Interface.PUBLIC;
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+
+import org.jclouds.openstack.keystone.catalog.ServiceEndpoint;
+import org.testng.annotations.Test;
+
+@Test(groups = "unit", testName = "ReturnRegionOrProviderTest")
+public class ReturnRegionOrProviderTest {
+   private final ReturnRegionOrProvider fn = new ReturnRegionOrProvider("openstack-keystone");
+
+   public void testRegionNotNullReturnsRegion() {
+      assertEquals(
+            fn.apply(ServiceEndpoint.builder().type("cdn").regionId("LON").version("1.0")
+                  .url(URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
+                  .iface(PUBLIC).build()), "LON");
+   }
+
+   public void testRegionNullReturnsProvider() {
+      assertEquals(
+            fn.apply(ServiceEndpoint.builder().type("cdn").version("1.0")
+                  .url(URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
+                  .iface(PUBLIC).build()), "openstack-keystone");
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/CredentialTypesTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/CredentialTypesTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/CredentialTypesTest.java
deleted file mode 100644
index a609630..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/CredentialTypesTest.java
+++ /dev/null
@@ -1,49 +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.keystone.v2_0.config;
-
-import static org.testng.Assert.assertEquals;
-
-import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableSet;
-
-@Test(groups = "unit", testName = "CredentialTypesTest")
-public class CredentialTypesTest {
-
-   public void testCredentialTypeOfWhenValid() {
-      assertEquals(CredentialTypes.credentialTypeOf(PasswordCredentials.createWithUsernameAndPassword("username",
-               "password")), CredentialTypes.PASSWORD_CREDENTIALS);
-   }
-
-   @Test(expectedExceptions = IllegalArgumentException.class)
-   public void testCredentialTypeOfWithoutAnnotation() {
-      CredentialTypes.credentialTypeOf("");
-   }
-
-   public void testIndexByCredentialTypeWhenValid() {
-      assertEquals(CredentialTypes.indexByCredentialType(
-               ImmutableSet.of(PasswordCredentials.createWithUsernameAndPassword("username", "password"))).keySet(),
-               ImmutableSet.of(CredentialTypes.PASSWORD_CREDENTIALS));
-   }
-
-   @Test(expectedExceptions = IllegalArgumentException.class)
-   public void testIndexByCredentialTypeWithoutAnnotation() {
-      CredentialTypes.indexByCredentialType(ImmutableSet.of(""));
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/ProviderModuleExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/ProviderModuleExpectTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/ProviderModuleExpectTest.java
deleted file mode 100644
index b40fcbf..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/config/ProviderModuleExpectTest.java
+++ /dev/null
@@ -1,176 +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.keystone.v2_0.config;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
-import static org.jclouds.util.Suppliers2.getLastValueInMap;
-import static org.testng.Assert.assertTrue;
-
-import java.io.Closeable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import java.net.URI;
-import java.util.Properties;
-
-import javax.inject.Qualifier;
-import javax.inject.Singleton;
-import javax.ws.rs.HEAD;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-
-import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
-import org.jclouds.apis.ApiMetadata;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpResponse;
-import org.jclouds.json.config.GsonModule.DateAdapter;
-import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
-import org.jclouds.location.suppliers.RegionIdToURISupplier;
-import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
-import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestApiExpectTest;
-import org.jclouds.rest.ConfiguresHttpApi;
-import org.jclouds.rest.annotations.ApiVersion;
-import org.jclouds.rest.annotations.Fallback;
-import org.jclouds.rest.config.HttpApiModule;
-import org.jclouds.rest.internal.BaseHttpApiMetadata;
-import org.jclouds.rest.internal.BaseRestApiExpectTest;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.Module;
-import com.google.inject.Provides;
-
-/**
- * Tests configuration via {@link ProviderModule}
- */
-@Test(groups = "unit", testName = "ProviderModuleExpectTest")
-public class ProviderModuleExpectTest extends BaseRestApiExpectTest<ProviderModuleExpectTest.DNSApi> {
-
-   @Retention(RUNTIME)
-   @Target(METHOD)
-   @Qualifier
-   static @interface DNS {
-   }
-
-   @ConfiguresHttpApi
-   public static class DNSHttpApiModule extends HttpApiModule<DNSApi> {
-
-      @Override
-      public void configure() {
-         bind(DateAdapter.class).to(Iso8601DateAdapter.class);
-         super.configure();
-      }
-
-      @Provides
-      @Singleton
-      @DNS
-      protected final Supplier<URI> provideCDNUrl(RegionIdToURISupplier.Factory factory, @ApiVersion String apiVersion) {
-         return getLastValueInMap(factory.createForApiTypeAndVersion("dns", apiVersion));
-      }
-   }
-
-   @org.jclouds.rest.annotations.Endpoint(DNS.class)
-   interface DNSApi extends Closeable {
-      @HEAD
-      @Path("/zones/{zoneName}")
-      @Fallback(FalseOnNotFoundOr404.class)
-      boolean zoneExists(@PathParam("zoneName") String zoneName);
-   }
-
-   public void testDNSEndpointApplied() {
-      KeystoneAuth keystoneAuth = new KeystoneAuth();
-
-      DNSApi api = requestsSendResponses(
-            keystoneAuth.getKeystoneAuthWithUsernameAndPassword(),
-            keystoneAuth.getResponseWithKeystoneAccess(),
-            HttpRequest.builder().method("HEAD").endpoint("http://172.16.0.1:8776/v1/3456/zones/foo.com").build(),
-            HttpResponse.builder().statusCode(200).build());
-      assertTrue(api.zoneExists("foo.com"));
-   }
-
-   private static class DNSApiMetadata extends BaseHttpApiMetadata<DNSApi> {
-
-      @Override
-      public Builder toBuilder() {
-         return new Builder().fromApiMetadata(this);
-      }
-
-      public DNSApiMetadata() {
-         this(new Builder());
-      }
-
-      protected DNSApiMetadata(Builder builder) {
-         super(builder);
-      }
-
-      public static Properties defaultProperties() {
-         Properties properties = BaseHttpApiMetadata.defaultProperties();
-         properties.setProperty(SERVICE_TYPE, "dns");
-         properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
-         return properties;
-      }
-
-      public static class Builder extends BaseHttpApiMetadata.Builder<DNSApi, Builder> {
-
-         protected Builder() {
-            id("dns")
-            .name("DNS API")
-            .identityName("${tenantName}:${userName} or ${userName}, if your keystone supports a default tenant")
-            .credentialName("${password}")
-            .endpointName("Keystone base url ending in /v2.0/")
-            .documentation(URI.create("http://dns"))
-            .version("1.0")
-            .defaultEndpoint("http://localhost:5000/v2.0/")
-            .defaultProperties(DNSApiMetadata.defaultProperties())
-            .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                        .add(AuthenticationApiModule.class)
-                                        .add(KeystoneAuthenticationModule.class)
-                                        .add(RegionModule.class)
-                                        .add(DNSHttpApiModule.class).build());
-         }
-
-         @Override
-         public DNSApiMetadata build() {
-            return new DNSApiMetadata(this);
-         }
-
-         @Override
-         protected Builder self() {
-            return this;
-         }
-      }
-   }
-
-   @Override
-   public ApiMetadata createApiMetadata() {
-      return new DNSApiMetadata();
-   }
-   
-   public static class KeystoneAuth extends BaseKeystoneRestApiExpectTest<KeystoneApi> {
-      public HttpRequest getKeystoneAuthWithUsernameAndPassword() {
-         return keystoneAuthWithUsernameAndPassword;
-      }
-      
-      public HttpResponse getResponseWithKeystoneAccess() {
-         return responseWithKeystoneAccess;
-      }
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/features/TokenApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/features/TokenApiLiveTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/features/TokenApiLiveTest.java
index af9e2d5..8cc3c69 100644
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/features/TokenApiLiveTest.java
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/features/TokenApiLiveTest.java
@@ -26,11 +26,11 @@ import java.util.Properties;
 import java.util.Set;
 
 import org.jclouds.http.HttpRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
 import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
 import org.jclouds.openstack.keystone.v2_0.domain.Token;
 import org.jclouds.openstack.keystone.v2_0.domain.User;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneApiLiveTest;
 import org.testng.annotations.Test;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/AdminURLTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/AdminURLTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/AdminURLTest.java
deleted file mode 100644
index 310d41b..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/AdminURLTest.java
+++ /dev/null
@@ -1,45 +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.keystone.v2_0.functions;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-import org.testng.annotations.Test;
-
-@Test(groups = "unit", testName = "AdminURLTest")
-public class AdminURLTest {
-   private final AdminURL fn = new AdminURL();
-
-   public void testAdminURL() {
-      assertEquals(fn.apply(
-               Endpoint.builder().region("LON").versionId("1.0").adminURL(
-                        URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
-                        .build()).get(), URI
-               .create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"));
-   }
-
-   public void testPublicURLNullReturnsInternalURL() {
-      assertEquals(fn
-               .apply(
-                        Endpoint.builder().region("lon").versionId("1.0")
-                                 .internalURL(URI.create("https://192.168.1.1")).build()).get(), null);
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/InternalURLTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/InternalURLTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/InternalURLTest.java
deleted file mode 100644
index 3f37825..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/InternalURLTest.java
+++ /dev/null
@@ -1,39 +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.keystone.v2_0.functions;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-import org.testng.annotations.Test;
-
-/**
- */
-@Test(groups = "unit", testName = "InternalURLTest")
-public class InternalURLTest {
-   private final InternalURL fn = new InternalURL();
-
-   public void testInternalURL() {
-      assertEquals(
-            fn.apply(
-                  Endpoint.builder().region("regionOne").versionId("2.0")
-                        .internalURL(URI.create("https://ericsson.com/v2/1900e98b-7272-4cbd-8e95-0b8c2a9266c0"))
-                        .build()).get(), URI.create("https://ericsson.com/v2/1900e98b-7272-4cbd-8e95-0b8c2a9266c0"));
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/PublicURLOrInternalIfNullTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/PublicURLOrInternalIfNullTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/PublicURLOrInternalIfNullTest.java
deleted file mode 100644
index 7e169ac..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/PublicURLOrInternalIfNullTest.java
+++ /dev/null
@@ -1,46 +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.keystone.v2_0.functions;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-import org.testng.annotations.Test;
-
-@Test(groups = "unit", testName = "PublicURLOrInternalIfNullTest")
-public class PublicURLOrInternalIfNullTest {
-   private final PublicURLOrInternalIfNull fn = new PublicURLOrInternalIfNull();
-
-   public void testPublicURLNotNullReturnsPublicURL() {
-      assertEquals(fn.apply(
-               Endpoint.builder().region("LON").versionId("1.0").publicURL(
-                        URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
-                        .build()).get(), URI
-               .create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"));
-   }
-
-   public void testPublicURLNullReturnsInternalURL() {
-      assertEquals(fn
-               .apply(
-                        Endpoint.builder().region("lon").versionId("1.0")
-                                 .internalURL(URI.create("https://192.168.1.1")).build()).get(), URI
-               .create("https://192.168.1.1"));
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/ReturnRegionOrProviderTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/ReturnRegionOrProviderTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/ReturnRegionOrProviderTest.java
deleted file mode 100644
index c606edd..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/functions/ReturnRegionOrProviderTest.java
+++ /dev/null
@@ -1,44 +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.keystone.v2_0.functions;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-import org.testng.annotations.Test;
-
-@Test(groups = "unit", testName = "ReturnRegionOrProviderTest")
-public class ReturnRegionOrProviderTest {
-   private final ReturnRegionOrProvider fn = new ReturnRegionOrProvider("openstack-keystone");
-
-   public void testRegionNotNullReturnsRegion() {
-      assertEquals(
-               fn.apply(Endpoint.builder().region("LON").versionId("1.0").publicURL(
-                        URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
-                        .build()), "LON");
-   }
-
-   public void testRegionNullReturnsProvider() {
-      assertEquals(
-               fn.apply(Endpoint.builder().versionId("1.0").publicURL(
-                        URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
-                        .build()), "openstack-keystone");
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/handlers/RetryOnRenewTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/handlers/RetryOnRenewTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/handlers/RetryOnRenewTest.java
deleted file mode 100644
index 840cda3..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/handlers/RetryOnRenewTest.java
+++ /dev/null
@@ -1,131 +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.keystone.v2_0.handlers;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import org.jclouds.domain.Credentials;
-import org.jclouds.http.HttpCommand;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpResponse;
-import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
-import org.jclouds.io.Payloads;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.testng.annotations.Test;
-
-import com.google.common.cache.LoadingCache;
-
-/**
- * Tests behavior of {@code RetryOnRenew} handler
- */
-@Test(groups = "unit", testName = "RetryOnRenewTest")
-public class RetryOnRenewTest {
-   @Test
-   public void test401ShouldRetry() {
-      HttpCommand command = createMock(HttpCommand.class);
-      HttpRequest request = createMock(HttpRequest.class);
-      HttpResponse response = createMock(HttpResponse.class);
-      @SuppressWarnings("unchecked")
-      LoadingCache<Credentials, Access> cache = createMock(LoadingCache.class);
-      BackoffLimitedRetryHandler backoffHandler = createMock(BackoffLimitedRetryHandler.class);
-
-      expect(command.getCurrentRequest()).andReturn(request);
-
-      cache.invalidateAll();
-      expectLastCall();
-
-      expect(response.getPayload()).andReturn(Payloads.newStringPayload("")).anyTimes();
-      expect(response.getStatusCode()).andReturn(401).atLeastOnce();
-
-      replay(command);
-      replay(response);
-      replay(cache);
-      replay(backoffHandler);
-
-      RetryOnRenew retry = new RetryOnRenew(cache, backoffHandler);
-
-      assertTrue(retry.shouldRetryRequest(command, response));
-
-      verify(command);
-      verify(response);
-      verify(cache);
-   }
-
-   @Test
-   public void test401ShouldRetry4Times() {
-      HttpCommand command = createMock(HttpCommand.class);
-      HttpRequest request = createMock(HttpRequest.class);
-      HttpResponse response = createMock(HttpResponse.class);
-
-      @SuppressWarnings("unchecked")
-      LoadingCache<Credentials, Access> cache = createMock(LoadingCache.class);
-      BackoffLimitedRetryHandler backoffHandler = createMock(BackoffLimitedRetryHandler.class);
-
-      expect(command.getCurrentRequest()).andReturn(request).anyTimes();
-      expect(request.getHeaders()).andStubReturn(null);
-
-      cache.invalidateAll();
-      expectLastCall().anyTimes();
-
-      expect(response.getPayload()).andReturn(Payloads.newStringPayload("")).anyTimes();
-      expect(response.getStatusCode()).andReturn(401).anyTimes();
-
-      replay(command, request, response, cache);
-
-      RetryOnRenew retry = new RetryOnRenew(cache, backoffHandler);
-
-      for (int i = 0; i < RetryOnRenew.NUM_RETRIES - 1; ++i) {
-         assertTrue(retry.shouldRetryRequest(command, response), "Expected retry to succeed");
-      }
-
-      assertFalse(retry.shouldRetryRequest(command, response), "Expected retry to fail on attempt " + RetryOnRenew.NUM_RETRIES);
-
-      verify(command, response, cache);
-   }
-
-   @Test
-   public void test408ShouldRetry() {
-      HttpCommand command = createMock(HttpCommand.class);
-      HttpResponse response = createMock(HttpResponse.class);
-      @SuppressWarnings("unchecked")
-      LoadingCache<Credentials, Access> cache = createMock(LoadingCache.class);
-      BackoffLimitedRetryHandler backoffHandler = createMock(BackoffLimitedRetryHandler.class);
-
-      expect(backoffHandler.shouldRetryRequest(command, response)).andReturn(true).once();
-      expect(response.getStatusCode()).andReturn(408).once();
-
-      replay(command);
-      replay(response);
-      replay(cache);
-      replay(backoffHandler);
-
-      RetryOnRenew retry = new RetryOnRenew(cache, backoffHandler);
-
-      assertTrue(retry.shouldRetryRequest(command, response));
-
-      verify(command);
-      verify(response);
-      verify(cache);
-      verify(backoffHandler);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneApiLiveTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneApiLiveTest.java
index ee85a5e..004d813 100644
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneApiLiveTest.java
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneApiLiveTest.java
@@ -19,8 +19,8 @@ package org.jclouds.openstack.keystone.v2_0.internal;
 import java.util.Properties;
 
 import org.jclouds.apis.BaseApiLiveTest;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
 import org.testng.annotations.Test;
 
 /**

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneRestApiExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneRestApiExpectTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneRestApiExpectTest.java
index 01fc644..1f19d96 100644
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneRestApiExpectTest.java
+++ b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeystoneRestApiExpectTest.java
@@ -16,7 +16,7 @@
  */
 package org.jclouds.openstack.keystone.v2_0.internal;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 
 import java.util.Properties;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
deleted file mode 100644
index f530329..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersionTest.java
+++ /dev/null
@@ -1,126 +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.keystone.v2_0.suppliers;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.inject.Singleton;
-
-import org.jclouds.location.Provider;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-import org.jclouds.openstack.keystone.v2_0.functions.EndpointToRegion;
-import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
-import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Provides;
-import com.google.inject.TypeLiteral;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
-
-@Test(groups = "unit", testName = "LocationIdToURIFromAccessForTypeAndVersionTest")
-public class LocationIdToURIFromAccessForTypeAndVersionTest {
-   private final LocationIdToURIFromAccessForTypeAndVersion.Factory factory = Guice.createInjector(new AbstractModule() {
-
-      @Override
-      protected void configure() {
-         bindConstant().annotatedWith(Provider.class).to("openstack-keystone");
-         bind(new TypeLiteral<Supplier<URI>>() {
-         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
-         bind(new TypeLiteral<Function<Endpoint, String>>(){}).to(EndpointToRegion.class);
-         install(new FactoryModuleBuilder().implement(LocationIdToURIFromAccessForTypeAndVersion.class,
-                  LocationIdToURIFromAccessForTypeAndVersion.class).build(
-                  LocationIdToURIFromAccessForTypeAndVersion.Factory.class));
-      }
-
-      @Provides
-      @Singleton
-      public Supplier<Access> provide() {
-         return Suppliers.ofInstance(new ParseAccessTest().expected());
-      }
-
-   }).getInstance(LocationIdToURIFromAccessForTypeAndVersion.Factory.class);
-
-   public void testRegionUnmatchesOkWhenNoVersionIdSet() {
-      assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "2").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI
-               .create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-2.region-a.geo-1", URI
-               .create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-3.region-a.geo-1", URI
-               .create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v2/3456")));
-   }
-
-   public void testRegionMatches() {
-      assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "2").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI
-               .create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-2.region-a.geo-1", URI
-               .create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-3.region-a.geo-1", URI
-               .create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v2/3456")));
-   }
-
-   private final LocationIdToURIFromAccessForTypeAndVersion.Factory raxFactory = Guice.createInjector(new AbstractModule() {
-
-      @Override
-      protected void configure() {
-         bindConstant().annotatedWith(Provider.class).to("rackspace");
-         bind(new TypeLiteral<Supplier<URI>>() {
-         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
-         bind(new TypeLiteral<Function<Endpoint, String>>(){}).to(EndpointToRegion.class);
-         install(new FactoryModuleBuilder().implement(LocationIdToURIFromAccessForTypeAndVersion.class,
-                  LocationIdToURIFromAccessForTypeAndVersion.class).build(
-                  LocationIdToURIFromAccessForTypeAndVersion.Factory.class));
-      }
-
-      @Provides
-      @Singleton
-      public Supplier<Access> provide() {
-         return Suppliers.ofInstance(new ParseRackspaceAccessTest().expected());
-      }
-   }).getInstance(LocationIdToURIFromAccessForTypeAndVersion.Factory.class);
-
-   @Test(expectedExceptions = NoSuchElementException.class)
-   public void testWhenNotInList() {
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("goo", "1.0").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("rackspace", URI
-               .create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-
-   public void testProviderWhenNoRegions() {
-      Map<String, URI> withNoRegions = Maps.transformValues(raxFactory.createForApiTypeAndVersion("compute", "1.0")
-            .get(), Suppliers.<URI> supplierFunction());
-      assertEquals(withNoRegions, ImmutableMap.of("rackspace", URI
-               .create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-
-   public void testOkWithNoVersions() {
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("rax:database", null).get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("DFW", URI
-               .create("https://dfw.databases.api.rackspacecloud.com/v1.0/40806637803162"), "ORD", URI
-               .create("https://ord.databases.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
deleted file mode 100644
index 91ebb61..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersionTest.java
+++ /dev/null
@@ -1,113 +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.keystone.v2_0.suppliers;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.inject.Singleton;
-
-import org.jclouds.location.Provider;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
-import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Provides;
-import com.google.inject.TypeLiteral;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
-
-@Test(groups = "unit", testName = "RegionIdToAdminURIFromAccessForTypeAndVersionTest")
-public class RegionIdToAdminURIFromAccessForTypeAndVersionTest {
-   private final RegionIdToAdminURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
-
-      @Override
-      protected void configure() {
-         bindConstant().annotatedWith(Provider.class).to("openstack-keystone");
-         bind(new TypeLiteral<Supplier<URI>>() {
-         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
-         install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
-                  RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
-      }
-
-      @Provides
-      @Singleton
-      public Supplier<Access> provide() {
-         return Suppliers.ofInstance(new ParseAccessTest().expected());
-      }
-   }).getInstance(RegionIdToAdminURISupplier.Factory.class);
-
-   public void testRegionMatches() {
-      assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("identity", "2.0").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("region-a.geo-1", URI.create("https://csnode.jclouds.org:35357/v2.0/")));
-      Map<String, URI> map = Maps.newLinkedHashMap();
-      map.put("region-a.geo-1", null);
-      map.put("region-b.geo-1", null);
-      map.put("region-c.geo-1", null);
-      assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "2").get(), Suppliers
-               .<URI> supplierFunction()), map);
-   }
-   
-   private final RegionIdToAdminURISupplier.Factory raxFactory = Guice.createInjector(new AbstractModule() {
-
-      @Override
-      protected void configure() {
-         bindConstant().annotatedWith(Provider.class).to("rackspace");
-         bind(new TypeLiteral<Supplier<URI>>() {
-         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
-         install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
-                  RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
-      }
-
-      @Provides
-      @Singleton
-      public Supplier<Access> provide() {
-         return Suppliers.ofInstance(new ParseRackspaceAccessTest().expected());
-      }
-   }).getInstance(RegionIdToAdminURISupplier.Factory.class);
-
-   @Test(expectedExceptions = NoSuchElementException.class)
-   public void testWhenNotInList() {
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("goo", "1.0").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("rackspace", URI
-               .create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-   
-   public void testProviderWhenNoRegions() {
-      Map<String, URI> map = Maps.newLinkedHashMap();
-      map.put("rackspace", null);
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("compute", "1.0").get(), Suppliers
-               .<URI> supplierFunction()), map);
-   }
-   
-   public void testOkWithNoVersions() {
-      Map<String, URI> map = Maps.newLinkedHashMap();
-      map.put("DFW", null);
-      map.put("ORD", null);
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("rax:database", null).get(), Suppliers
-               .<URI> supplierFunction()), map);
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
deleted file mode 100644
index 0b48360..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionTest.java
+++ /dev/null
@@ -1,118 +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.keystone.v2_0.suppliers;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-import java.util.NoSuchElementException;
-
-import javax.inject.Singleton;
-
-import org.jclouds.location.Provider;
-import org.jclouds.location.suppliers.RegionIdToURISupplier;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
-import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Provides;
-import com.google.inject.TypeLiteral;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
-
-@Test(groups = "unit", testName = "RegionIdToURIFromAccessForTypeAndVersionTest")
-public class RegionIdToURIFromAccessForTypeAndVersionTest {
-   private final RegionIdToURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
-
-      @Override
-      protected void configure() {
-         bindConstant().annotatedWith(Provider.class).to("openstack-keystone");
-         bind(new TypeLiteral<Supplier<URI>>() {
-         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
-         install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
-                  RegionIdToURIFromAccessForTypeAndVersion.class).build(
-                  RegionIdToURISupplier.Factory.class));
-      }
-
-      @Provides
-      @Singleton
-      public Supplier<Access> provide() {
-         return Suppliers.ofInstance(new ParseAccessTest().expected());
-      }
-   }).getInstance(RegionIdToURISupplier.Factory.class);
-
-   @SuppressWarnings("CheckReturnValue")
-   @Test(expectedExceptions = NoSuchElementException.class)
-   public void testRegionUnmatches() {
-      Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.0").get(),
-               Suppliers.<URI> supplierFunction());
-   }
-   
-   public void testRegionMatches() {
-      assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "2").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI
-               .create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-2.region-a.geo-1", URI
-               .create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"), "az-3.region-a.geo-1", URI
-               .create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v2/3456")));
-   }
-
-   private final RegionIdToURISupplier.Factory raxFactory = Guice.createInjector(new AbstractModule() {
-
-      @Override
-      protected void configure() {
-         bindConstant().annotatedWith(Provider.class).to("rackspace");
-         bind(new TypeLiteral<Supplier<URI>>() {
-         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));
-         install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
-                  RegionIdToURIFromAccessForTypeAndVersion.class).build(
-                  RegionIdToURISupplier.Factory.class));
-      }
-
-      @Provides
-      @Singleton
-      public Supplier<Access> provide() {
-         return Suppliers.ofInstance(new ParseRackspaceAccessTest().expected());
-      }
-   }).getInstance(RegionIdToURISupplier.Factory.class);
-
-   @Test(expectedExceptions = NoSuchElementException.class)
-   public void testWhenNotInList() {
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("goo", "1.0").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("rackspace", URI
-               .create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-
-   public void testProviderWhenNoRegions() {
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("compute", "1.0").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("rackspace", URI
-               .create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-
-   public void testOkWithNoVersions() {
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("rax:database", null).get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("DFW", URI
-               .create("https://dfw.databases.api.rackspacecloud.com/v1.0/40806637803162"), "ORD", URI
-               .create("https://ord.databases.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionTest.java b/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionTest.java
deleted file mode 100644
index b716bbc..0000000
--- a/apis/openstack-keystone/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionTest.java
+++ /dev/null
@@ -1,113 +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.keystone.v2_0.suppliers;
-
-import static org.testng.Assert.assertEquals;
-
-import java.net.URI;
-import java.util.NoSuchElementException;
-
-import javax.inject.Singleton;
-
-import org.jclouds.location.Provider;
-import org.jclouds.location.suppliers.ZoneIdToURISupplier;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
-import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
-import com.google.inject.Provides;
-import com.google.inject.TypeLiteral;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
-
-@Test(groups = "unit", testName = "ZoneIdToURIFromAccessForTypeAndVersionSupplierTest")
-public class ZoneIdToURIFromAccessForTypeAndVersionTest {
-   private final ZoneIdToURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
-
-      @Override
-      protected void configure() {
-         bindConstant().annotatedWith(Provider.class).to("rackspace");
-         bind(new TypeLiteral<Supplier<URI>>() {
-         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));         
-         install(new FactoryModuleBuilder().implement(ZoneIdToURISupplier.class,
-                  ZoneIdToURIFromAccessForTypeAndVersion.class).build(ZoneIdToURISupplier.Factory.class));
-      }
-
-      @Provides
-      @Singleton
-      public Supplier<Access> provide() {
-         return Suppliers.ofInstance(new ParseAccessTest().expected());
-      }
-   }).getInstance(ZoneIdToURISupplier.Factory.class);
-
-
-   @SuppressWarnings("CheckReturnValue")
-   @Test(expectedExceptions = NoSuchElementException.class)
-   public void testZoneUnmatches() {
-      Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.0").get(),
-               Suppliers.<URI> supplierFunction());
-   }
-  
-   public void testZoneMatches() {
-      assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "2").get(), Suppliers
-            .<URI> supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"),
-                                                        "az-2.region-a.geo-1", URI.create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v2/3456"),
-                                                        "az-3.region-a.geo-1", URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v2/3456")));
-   }
-   
-   private final ZoneIdToURISupplier.Factory raxFactory = Guice.createInjector(new AbstractModule() {
-
-      @Override
-      protected void configure() {
-         bindConstant().annotatedWith(Provider.class).to("rackspace");
-         bind(new TypeLiteral<Supplier<URI>>() {
-         }).annotatedWith(Provider.class).toInstance(Suppliers.ofInstance(URI.create("https://identity")));        
-         install(new FactoryModuleBuilder().implement(ZoneIdToURISupplier.class,
-                  ZoneIdToURIFromAccessForTypeAndVersion.class).build(ZoneIdToURISupplier.Factory.class));
-      }
-
-      @Provides
-      @Singleton
-      public Supplier<Access> provide() {
-         return Suppliers.ofInstance(new ParseRackspaceAccessTest().expected());
-      }
-   }).getInstance(ZoneIdToURISupplier.Factory.class);
-
-   @Test(expectedExceptions = NoSuchElementException.class)
-   public void testWhenNotInList() {
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("goo", "1.0").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("rackspace", URI
-               .create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-
-   public void testProviderWhenNoZones() {
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("compute", "1.0").get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("rackspace", URI.create("https://servers.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-   
-   public void testOkWithNoVersions() {
-      assertEquals(Maps.transformValues(raxFactory.createForApiTypeAndVersion("rax:database", null).get(), Suppliers
-               .<URI> supplierFunction()), ImmutableMap.of("DFW", URI.create("https://dfw.databases.api.rackspacecloud.com/v1.0/40806637803162"),
-                                                           "ORD", URI.create("https://ord.databases.api.rackspacecloud.com/v1.0/40806637803162")));
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 d73a1da..a330afa 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
@@ -17,8 +17,9 @@
 package org.jclouds.openstack.nova.v2_0;
 
 import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 import static org.jclouds.openstack.nova.v2_0.config.NovaProperties.AUTO_ALLOCATE_FLOATING_IPS;
 import static org.jclouds.openstack.nova.v2_0.config.NovaProperties.AUTO_GENERATE_KEYPAIRS;
 import static org.jclouds.openstack.nova.v2_0.config.NovaProperties.TIMEOUT_SECURITYGROUP_PRESENT;
@@ -29,10 +30,10 @@ import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
 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.RegionModule;
+import org.jclouds.openstack.keystone.auth.config.AuthenticationModule;
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.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;
@@ -69,6 +70,7 @@ public class NovaApiMetadata extends BaseHttpApiMetadata<NovaApi>  {
       properties.setProperty("jclouds.ssh.retry-auth", "true");
       properties.setProperty(SERVICE_TYPE, ServiceType.COMPUTE);
       properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       properties.setProperty(AUTO_ALLOCATE_FLOATING_IPS, "false");
       properties.setProperty(AUTO_GENERATE_KEYPAIRS, "false");
       properties.setProperty(TIMEOUT_SECURITYGROUP_PRESENT, "500");
@@ -93,8 +95,8 @@ public class NovaApiMetadata extends BaseHttpApiMetadata<NovaApi>  {
          .defaultProperties(NovaApiMetadata.defaultProperties())
          .view(typeToken(ComputeServiceContext.class))
          .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                     .add(AuthenticationApiModule.class)
-                                     .add(KeystoneAuthenticationModule.class)
+                                     .add(AuthenticationModule.class)
+                                     .add(ServiceCatalogModule.class)
                                      .add(RegionModule.class)
                                      .add(NovaParserModule.class)
                                      .add(NovaHttpApiModule.class)

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AttachInterfaceApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AttachInterfaceApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AttachInterfaceApi.java
index 65bd198..119b08a 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AttachInterfaceApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AttachInterfaceApi.java
@@ -29,7 +29,7 @@ import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.InterfaceAttachment;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AvailabilityZoneApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AvailabilityZoneApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AvailabilityZoneApi.java
index 9aa9b21..e3abe74 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AvailabilityZoneApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/AvailabilityZoneApi.java
@@ -23,7 +23,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.regionscoped.AvailabilityZone;
 import org.jclouds.openstack.nova.v2_0.domain.regionscoped.AvailabilityZoneDetails;
 import org.jclouds.openstack.v2_0.ServiceType;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ConsolesApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ConsolesApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ConsolesApi.java
index 7aa1f60..a4d4127 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ConsolesApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ConsolesApi.java
@@ -25,7 +25,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 
 import org.jclouds.fallbacks.MapHttp4xxCodesToExceptions;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.binders.BindConsoleToJsonPayload;
 import org.jclouds.openstack.nova.v2_0.domain.Console;
 import org.jclouds.openstack.v2_0.ServiceType;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FlavorExtraSpecsApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FlavorExtraSpecsApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FlavorExtraSpecsApi.java
index 0db8cee..d935763 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FlavorExtraSpecsApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FlavorExtraSpecsApi.java
@@ -33,7 +33,7 @@ import org.jclouds.Fallbacks.EmptyMapOnNotFoundOr404;
 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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPApi.java
index 626ee2d..003e66b 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPApi.java
@@ -29,7 +29,7 @@ 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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApi.java
index ead37ab..5bf5625 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApi.java
@@ -22,7 +22,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.FloatingIPPool;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAdministrationApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAdministrationApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAdministrationApi.java
index 8a07d3f..5eadc48 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAdministrationApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HostAdministrationApi.java
@@ -26,7 +26,7 @@ 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.keystone.auth.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;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 889bb4f..18ad082 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
@@ -32,7 +32,7 @@ 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.keystone.auth.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;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HypervisorApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HypervisorApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HypervisorApi.java
index 8da914c..9e443f6 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HypervisorApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/HypervisorApi.java
@@ -23,7 +23,7 @@ import javax.ws.rs.Path;
 import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.regionscoped.Hypervisor;
 import org.jclouds.openstack.nova.v2_0.domain.regionscoped.HypervisorDetails;
 import org.jclouds.openstack.v2_0.ServiceType;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 d9f87d3..34074d1 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
@@ -30,7 +30,7 @@ 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.keystone.auth.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;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 5790620..59a5dd5 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
@@ -27,7 +27,7 @@ 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.keystone.auth.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;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 7e2b503..9d3ed0f 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
@@ -30,7 +30,7 @@ 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.keystone.auth.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;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 e054bd9..b489b2a 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
@@ -25,7 +25,7 @@ import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
 
 import org.jclouds.fallbacks.MapHttp4xxCodesToExceptions;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.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;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 3d1ecba..e17ca69 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
@@ -25,7 +25,7 @@ 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.keystone.auth.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;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 269059b..f88b480 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
@@ -26,7 +26,7 @@ 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.keystone.auth.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;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 eff19a0..f484cff 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
@@ -24,7 +24,7 @@ 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.keystone.auth.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;


[2/8] jclouds git commit: Initial work towards Keystone V3 authentication

Posted by na...@apache.org.
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/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 eeaa992..185c807 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
@@ -30,7 +30,7 @@ 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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.Volume;
 import org.jclouds.openstack.nova.v2_0.domain.VolumeSnapshot;
 import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApi.java
index 4445b3e..8d329f1 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeAttachmentApi.java
@@ -30,7 +30,7 @@ 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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApi.java
index 1204066..05dafac 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/VolumeTypeApi.java
@@ -34,7 +34,7 @@ import org.jclouds.Fallbacks.EmptyMapOnNotFoundOr404;
 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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.VolumeType;
 import org.jclouds.openstack.nova.v2_0.options.CreateVolumeTypeOptions;
 import org.jclouds.openstack.v2_0.ServiceType;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/FlavorApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/FlavorApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/FlavorApi.java
index d9e1498..98d1d9f 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/FlavorApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/FlavorApi.java
@@ -31,8 +31,8 @@ import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.domain.Flavor;
 import org.jclouds.openstack.nova.v2_0.functions.internal.ParseFlavorDetails;
 import org.jclouds.openstack.nova.v2_0.functions.internal.ParseFlavors;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageApi.java
index 1258c79..3dc9907 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageApi.java
@@ -36,8 +36,8 @@ import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.binders.BindMetadataToJsonPayload;
 import org.jclouds.openstack.nova.v2_0.domain.Image;
 import org.jclouds.openstack.nova.v2_0.functions.internal.OnlyMetadataValueOrNull;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerApi.java
index 42ab1c7..33bf09a 100644
--- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerApi.java
+++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerApi.java
@@ -41,8 +41,8 @@ import org.jclouds.collect.PagedIterable;
 import org.jclouds.fallbacks.MapHttp4xxCodesToExceptions;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.nova.v2_0.binders.BindMetadataToJsonPayload;
 import org.jclouds.openstack.nova.v2_0.domain.RebootType;
 import org.jclouds.openstack.nova.v2_0.domain.Server;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAndTenantIdAuthenticationExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAndTenantIdAuthenticationExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAndTenantIdAuthenticationExpectTest.java
index a19dc75..8c18292 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAndTenantIdAuthenticationExpectTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAndTenantIdAuthenticationExpectTest.java
@@ -31,7 +31,7 @@ import com.google.common.collect.ImmutableSet;
 
 /**
  *
- * @see org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties#CREDENTIAL_TYPE
+ * @see org.jclouds.openstack.keystone.config.KeystoneProperties#CREDENTIAL_TYPE
  */
 @Test(groups = "unit", testName = "AccessKeyAndSecretKeyAndTenantIdAuthenticationExpectTest")
 public class AccessKeyAndSecretKeyAndTenantIdAuthenticationExpectTest extends BaseNovaApiExpectTest {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAuthenticationExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAuthenticationExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAuthenticationExpectTest.java
index bd3f714..54aba76 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAuthenticationExpectTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/AccessKeyAndSecretKeyAuthenticationExpectTest.java
@@ -30,7 +30,7 @@ import com.google.common.collect.ImmutableSet;
 
 /**
  *
- * @see org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties#CREDENTIAL_TYPE
+ * @see org.jclouds.openstack.keystone.config.KeystoneProperties#CREDENTIAL_TYPE
  */
 @Test(groups = "unit", testName = "AccessKeyAndSecretKeyAuthenticationExpectTest")
 public class AccessKeyAndSecretKeyAuthenticationExpectTest extends BaseNovaApiExpectTest {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationExpectTest.java
index 55f1a21..dac895e 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationExpectTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationExpectTest.java
@@ -28,7 +28,7 @@ import com.google.common.collect.ImmutableSet;
 
 /**
  *
- * @see org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties#CREDENTIAL_TYPE
+ * @see org.jclouds.openstack.keystone.config.KeystoneProperties#CREDENTIAL_TYPE
  */
 @Test(groups = "unit", testName = "PasswordAuthenticationExpectTest")
 public class PasswordAuthenticationExpectTest extends BaseNovaApiExpectTest {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationWithTenantNameExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationWithTenantNameExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationWithTenantNameExpectTest.java
index 87d3f37..4761a6e 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationWithTenantNameExpectTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/PasswordAuthenticationWithTenantNameExpectTest.java
@@ -30,7 +30,7 @@ import com.google.common.collect.ImmutableSet;
 
 /**
  *
- * @see org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties#CREDENTIAL_TYPE
+ * @see org.jclouds.openstack.keystone.config.KeystoneProperties#CREDENTIAL_TYPE
  */
 @Test(groups = "unit", testName = "PasswordAuthenticationWithTenantNameExpectTest")
 public class PasswordAuthenticationWithTenantNameExpectTest extends BaseNovaApiExpectTest {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceLiveTest.java
index f5e33dd..d4aac07 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceLiveTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/compute/NovaComputeServiceLiveTest.java
@@ -21,7 +21,7 @@ import static java.util.logging.Logger.getAnonymousLogger;
 import java.util.Properties;
 
 import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.openstack.nova.v2_0.config.NovaProperties;
 import org.jclouds.rest.AuthorizationException;
 import org.jclouds.sshj.config.SshjSshClientModule;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/functions/InternalURLLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/functions/InternalURLLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/functions/InternalURLLiveTest.java
index 602831c..713c1b9 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/functions/InternalURLLiveTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/functions/InternalURLLiveTest.java
@@ -21,8 +21,8 @@ import static org.testng.Assert.assertNotNull;
 
 import java.util.Properties;
 
+import org.jclouds.openstack.keystone.catalog.config.InternalUrlModule;
 import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
-import org.jclouds.openstack.v2_0.config.InternalUrlModule;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/internal/BaseNovaApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/internal/BaseNovaApiLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/internal/BaseNovaApiLiveTest.java
index 614fad2..13b34d1 100644
--- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/internal/BaseNovaApiLiveTest.java
+++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/internal/BaseNovaApiLiveTest.java
@@ -20,7 +20,7 @@ import java.util.Properties;
 import java.util.Set;
 
 import org.jclouds.apis.BaseApiLiveTest;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.openstack.nova.v2_0.NovaApi;
 import org.jclouds.openstack.nova.v2_0.config.NovaProperties;
 import org.jclouds.openstack.nova.v2_0.domain.Flavor;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
index 7351f68..3de0853 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/SwiftApiMetadata.java
@@ -17,21 +17,22 @@
 package org.jclouds.openstack.swift.v1;
 
 import static org.jclouds.Constants.PROPERTY_IDEMPOTENT_METHODS;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
-import static org.jclouds.openstack.swift.v1.reference.TempAuthHeaders.TEMP_AUTH_HEADER_USER;
-import static org.jclouds.openstack.swift.v1.reference.TempAuthHeaders.TEMP_AUTH_HEADER_PASS;
-import static org.jclouds.openstack.swift.v1.reference.TempAuthHeaders.DEFAULT_HEADER_USER;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 import static org.jclouds.openstack.swift.v1.reference.TempAuthHeaders.DEFAULT_HEADER_PASS;
+import static org.jclouds.openstack.swift.v1.reference.TempAuthHeaders.DEFAULT_HEADER_USER;
+import static org.jclouds.openstack.swift.v1.reference.TempAuthHeaders.TEMP_AUTH_HEADER_PASS;
+import static org.jclouds.openstack.swift.v1.reference.TempAuthHeaders.TEMP_AUTH_HEADER_USER;
 import static org.jclouds.reflect.Reflection2.typeToken;
 
-
 import java.net.URI;
 import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
-import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.swift.v1.blobstore.RegionScopedBlobStoreContext;
 import org.jclouds.openstack.swift.v1.blobstore.config.SignUsingTemporaryUrls;
 import org.jclouds.openstack.swift.v1.blobstore.config.SwiftBlobStoreContextModule;
@@ -64,6 +65,7 @@ public class SwiftApiMetadata extends BaseHttpApiMetadata<SwiftApi> {
    public static Properties defaultProperties() {
       Properties properties = BaseHttpApiMetadata.defaultProperties();
       properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       properties.setProperty(PROPERTY_IDEMPOTENT_METHODS, "DELETE,GET,HEAD,OPTIONS,POST,PUT");
       // Can alternatively be set to "tempAuthCredentials"
       properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
@@ -87,6 +89,7 @@ public class SwiftApiMetadata extends BaseHttpApiMetadata<SwiftApi> {
          .view(typeToken(RegionScopedBlobStoreContext.class))
          .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
                                      .add(SwiftAuthenticationModule.class)
+                                     .add(ServiceCatalogModule.class)
                                      .add(RegionModule.class)
                                      .add(SwiftTypeAdapters.class)
                                      .add(SwiftHttpApiModule.class)

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftAuthenticationModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftAuthenticationModule.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftAuthenticationModule.java
index 90f1255..a32276a 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftAuthenticationModule.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/config/SwiftAuthenticationModule.java
@@ -18,11 +18,11 @@ package org.jclouds.openstack.swift.v1.config;
 
 import static org.jclouds.http.HttpUtils.releasePayload;
 import static org.jclouds.http.Uris.uriBuilder;
-import static org.jclouds.openstack.v2_0.ServiceType.OBJECT_STORE;
-import static org.jclouds.openstack.v2_0.reference.AuthHeaders.AUTH_TOKEN;
-import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
+import static org.jclouds.openstack.keystone.auth.AuthHeaders.AUTH_TOKEN;
 import static org.jclouds.openstack.swift.v1.reference.TempAuthHeaders.STORAGE_URL;
 import static org.jclouds.openstack.swift.v1.reference.TempAuthHeaders.TEMP_AUTH_HEADER_USER;
+import static org.jclouds.openstack.v2_0.ServiceType.OBJECT_STORE;
+import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
 
 import java.io.Closeable;
 import java.net.URI;
@@ -38,8 +38,8 @@ import org.jclouds.ContextBuilder;
 import org.jclouds.domain.Credentials;
 import org.jclouds.http.HttpRequest;
 import org.jclouds.http.HttpResponse;
-import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
+import org.jclouds.openstack.keystone.auth.config.AuthenticationModule;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
 import org.jclouds.openstack.keystone.v2_0.domain.Access;
 import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
 import org.jclouds.openstack.keystone.v2_0.domain.Service;
@@ -59,33 +59,34 @@ import com.google.inject.Injector;
 import com.google.inject.name.Named;
 
 /**
- * When {@link org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties#CREDENTIAL_TYPE} is set to {@code
+ * When {@link org.jclouds.openstack.keystone.config.KeystoneProperties#CREDENTIAL_TYPE} is set to {@code
  * tempAuthCredentials}, do not use Keystone. Instead, bridge TempAuth to Keystone by faking a service catalog out of
  * the storage url. The {@link ContextBuilder#endpoint(String) endpoint} must be set to the TempAuth url, usually ending
  * in {@code auth/v1.0/}.
  */
-public final class SwiftAuthenticationModule extends KeystoneAuthenticationModule {
+public final class SwiftAuthenticationModule extends AuthenticationModule {
    @Override
    protected void configure() {
       super.configure();
-      bindHttpApi(binder(), AuthenticationApi.class);
       bindHttpApi(binder(), TempAuthApi.class);
    }
 
-   @Override protected Map<String, Function<Credentials, Access>> authenticationMethods(Injector i) {
-      return ImmutableMap.<String, Function<Credentials, Access>>builder()
-                         .putAll(super.authenticationMethods(i))
-                         .put("tempAuthCredentials", i.getInstance(TempAuth.class)).build();
+   @Override
+   protected Map<String, Function<Credentials, AuthInfo>> authenticationMethods(Injector i) {
+      return ImmutableMap.<String, Function<Credentials, AuthInfo>> builder()
+            .putAll(super.authenticationMethods(i))
+            .put("tempAuthCredentials", i.getInstance(TempAuth.class))
+            .build();
    }
    
-   static final class TempAuth implements Function<Credentials, Access> {
+   static final class TempAuth implements Function<Credentials, AuthInfo> {
       private final TempAuthApi delegate;
 
       @Inject TempAuth(TempAuthApi delegate) {
          this.delegate = delegate;
       }
 
-      @Override public Access apply(Credentials input) {
+      @Override public AuthInfo apply(Credentials input) {
          return delegate.auth(input);
       }
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
index 63911db..6db8d7b 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/AccountApi.java
@@ -28,7 +28,7 @@ import javax.ws.rs.HeaderParam;
 import javax.ws.rs.POST;
 
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindAccountMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveAccountMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.domain.Account;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
index b62322f..ebf1e5b 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/BulkApi.java
@@ -32,7 +32,7 @@ import javax.ws.rs.QueryParam;
 import org.jclouds.http.HttpRequest;
 import org.jclouds.io.Payload;
 import org.jclouds.io.Payloads;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.swift.v1.binders.SetPayload;
 import org.jclouds.openstack.swift.v1.domain.BulkDeleteResponse;
 import org.jclouds.openstack.swift.v1.domain.ExtractArchiveResponse;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
index 7a28fbc..e942e71 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ContainerApi.java
@@ -34,7 +34,7 @@ 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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.swift.v1.SwiftFallbacks.TrueOn404FalseOn409;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindContainerMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveContainerMetadataToHeaders;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/DynamicLargeObjectApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/DynamicLargeObjectApi.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/DynamicLargeObjectApi.java
index 044e457..de4c61d 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/DynamicLargeObjectApi.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/DynamicLargeObjectApi.java
@@ -26,7 +26,7 @@ import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindObjectMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.BindToHeaders;
 import org.jclouds.openstack.swift.v1.domain.SwiftObject;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
index 24d8450..41cbeb6 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/ObjectApi.java
@@ -18,8 +18,8 @@ package org.jclouds.openstack.swift.v1.features;
 
 import static com.google.common.net.HttpHeaders.EXPECT;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_COPY_FROM;
 import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_COPY_FRESH_METADATA;
+import static org.jclouds.openstack.swift.v1.reference.SwiftHeaders.OBJECT_COPY_FROM;
 
 import java.util.Map;
 
@@ -41,7 +41,7 @@ import org.jclouds.blobstore.KeyNotFoundException;
 import org.jclouds.http.options.GetOptions;
 import org.jclouds.io.Payload;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindObjectMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindRemoveObjectMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.BindToHeaders;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
index d5d490d..78cef14 100644
--- a/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
+++ b/apis/openstack-swift/src/main/java/org/jclouds/openstack/swift/v1/features/StaticLargeObjectApi.java
@@ -31,11 +31,12 @@ import javax.ws.rs.PathParam;
 
 import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.swift.v1.binders.BindMetadataToHeaders.BindObjectMetadataToHeaders;
 import org.jclouds.openstack.swift.v1.binders.BindToHeaders;
 import org.jclouds.openstack.swift.v1.domain.DeleteStaticLargeObjectResponse;
 import org.jclouds.openstack.swift.v1.domain.Segment;
+import org.jclouds.openstack.swift.v1.domain.SwiftObject;
 import org.jclouds.openstack.swift.v1.functions.ETagHeader;
 import org.jclouds.rest.annotations.BinderParam;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TempAuthMockTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TempAuthMockTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TempAuthMockTest.java
index 685a232..6b9a865 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TempAuthMockTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/TempAuthMockTest.java
@@ -19,7 +19,7 @@ package org.jclouds.openstack.swift.v1;
 import static com.google.common.util.concurrent.MoreExecutors.newDirectExecutorService;
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedBlobStoreContextLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedBlobStoreContextLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedBlobStoreContextLiveTest.java
index 97f5448..5ae1075 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedBlobStoreContextLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedBlobStoreContextLiveTest.java
@@ -16,7 +16,7 @@
  */
 package org.jclouds.openstack.swift.v1.blobstore;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStoreParallelLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStoreParallelLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStoreParallelLiveTest.java
index f2d0c84..a346d7b 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStoreParallelLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/RegionScopedSwiftBlobStoreParallelLiveTest.java
@@ -18,7 +18,7 @@ package org.jclouds.openstack.swift.v1.blobstore;
 
 import static org.assertj.core.util.Files.delete;
 import static org.jclouds.blobstore.options.PutOptions.Builder.multipart;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 import static org.testng.Assert.assertEquals;
 
 import java.io.File;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
index 3cb015e..6995c81 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobIntegrationLiveTest.java
@@ -18,7 +18,7 @@ package org.jclouds.openstack.swift.v1.blobstore.integration;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 
 import java.util.Properties;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
index d9996bf..402c09a 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobLiveTest.java
@@ -16,7 +16,7 @@
  */
 package org.jclouds.openstack.swift.v1.blobstore.integration;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 
 import java.util.Properties;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
index 9dd603f..a54b3bf 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftBlobSignerLiveTest.java
@@ -16,7 +16,7 @@
  */
 package org.jclouds.openstack.swift.v1.blobstore.integration;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 
 import java.util.Properties;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
index fc8746b..a0614cc 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerIntegrationLiveTest.java
@@ -16,14 +16,14 @@
  */
 package org.jclouds.openstack.swift.v1.blobstore.integration;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 import static org.testng.Assert.assertTrue;
 
 import java.util.Properties;
 
 import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest;
-import org.testng.annotations.Test;
 import org.testng.SkipException;
+import org.testng.annotations.Test;
 
 @Test(groups = "live", testName = "SwiftContainerIntegrationLiveTest")
 public class SwiftContainerIntegrationLiveTest extends BaseContainerIntegrationTest {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
index 9bd85d6..608ddb6 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftContainerLiveTest.java
@@ -16,7 +16,7 @@
  */
 package org.jclouds.openstack.swift.v1.blobstore.integration;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 
 import java.util.Properties;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
index 1da1a68..3b7ec9d 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/blobstore/integration/SwiftServiceIntegrationLiveTest.java
@@ -16,7 +16,7 @@
  */
 package org.jclouds.openstack.swift.v1.blobstore.integration;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 
 import java.util.Properties;
 

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
index 57d4b0a..9beba1f 100644
--- a/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
+++ b/apis/openstack-swift/src/test/java/org/jclouds/openstack/swift/v1/internal/BaseSwiftApiLiveTest.java
@@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
 import org.jclouds.location.reference.LocationConstants;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.openstack.swift.v1.SwiftApi;
 import org.jclouds.openstack.swift.v1.domain.BulkDeleteResponse;
 import org.jclouds.openstack.swift.v1.domain.ObjectList;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApi.java b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApi.java
index 25869fb..579c635 100644
--- a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApi.java
+++ b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApi.java
@@ -24,7 +24,6 @@ import javax.ws.rs.PathParam;
 
 import org.jclouds.location.Region;
 import org.jclouds.location.functions.RegionToEndpoint;
-import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
 import org.jclouds.openstack.trove.v1.features.DatabaseApi;
 import org.jclouds.openstack.trove.v1.features.FlavorApi;
 import org.jclouds.openstack.trove.v1.features.InstanceApi;
@@ -132,5 +131,5 @@ public interface TroveApi extends Closeable {
     * Provides the Tenant.
     */
    @Provides
-   Optional<Tenant> getCurrentTenantId();
+   Optional<String> getCurrentTenantId();
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApiMetadata.java b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApiMetadata.java
index 3d5e469..034c534 100644
--- a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApiMetadata.java
+++ b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/TroveApiMetadata.java
@@ -16,17 +16,18 @@
  */
 package org.jclouds.openstack.trove.v1;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 
 import java.net.URI;
 import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
-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.RegionModule;
+import org.jclouds.openstack.keystone.auth.config.AuthenticationModule;
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.trove.v1.config.TroveHttpApiModule;
 import org.jclouds.openstack.trove.v1.config.TroveParserModule;
 import org.jclouds.openstack.v2_0.ServiceType;
@@ -58,6 +59,7 @@ public class TroveApiMetadata extends BaseHttpApiMetadata<TroveApi> {
    public static Properties defaultProperties() {
       Properties properties = BaseHttpApiMetadata.defaultProperties();
       properties.setProperty(SERVICE_TYPE, ServiceType.DATABASE);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
       return properties;
    }
@@ -75,8 +77,8 @@ public class TroveApiMetadata extends BaseHttpApiMetadata<TroveApi> {
          .defaultEndpoint("http://localhost:5000/v2.0/")
          .defaultProperties(TroveApiMetadata.defaultProperties())
          .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                     .add(AuthenticationApiModule.class)
-                                     .add(KeystoneAuthenticationModule.class)
+                                     .add(AuthenticationModule.class)
+                                     .add(ServiceCatalogModule.class)
                                      .add(RegionModule.class)
                                      .add(TroveParserModule.class)
                                      .add(TroveHttpApiModule.class)

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/config/TroveHttpApiModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/config/TroveHttpApiModule.java b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/config/TroveHttpApiModule.java
index 1bf6404..ce535f8 100644
--- a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/config/TroveHttpApiModule.java
+++ b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/config/TroveHttpApiModule.java
@@ -26,8 +26,10 @@ import org.jclouds.http.annotation.Redirection;
 import org.jclouds.http.annotation.ServerError;
 import org.jclouds.json.config.GsonModule.DateAdapter;
 import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
 import org.jclouds.openstack.keystone.v2_0.domain.Access;
 import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
+import org.jclouds.openstack.keystone.v3.domain.Token;
 import org.jclouds.openstack.trove.v1.TroveApi;
 import org.jclouds.openstack.trove.v1.handlers.TroveErrorHandler;
 import org.jclouds.rest.ConfiguresHttpApi;
@@ -67,14 +69,24 @@ public class TroveHttpApiModule extends HttpApiModule<TroveApi> {
    }
    
    @Provides
-   final Supplier<Optional<Tenant>> supplyTenant(Supplier<Access> access) {
+   final Supplier<Optional<String>> supplyTenant(Supplier<AuthInfo> access) {
       return Suppliers.compose(GetTenant.INSTANCE, access);
    }
    
-   private static enum GetTenant implements Function<Access, Optional<Tenant>> {
+   private static enum GetTenant implements Function<AuthInfo, Optional<String>> {
       INSTANCE;
-      public Optional<Tenant> apply(Access in){
-         return in.getToken().getTenant();
+      public Optional<String> apply(AuthInfo in) {
+         if (in instanceof Access) {
+            return Access.class.cast(in).getToken().getTenant().transform(new Function<Tenant, String>() {
+               @Override
+               public String apply(Tenant input) {
+                  return input.getId();
+               }
+            });
+         } else if (in instanceof Token) {
+            return Optional.of(Token.class.cast(in).user().domain().id());
+         }
+         return Optional.absent();
       }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/DatabaseApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/DatabaseApi.java b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/DatabaseApi.java
index d640622..ef0fe27 100644
--- a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/DatabaseApi.java
+++ b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/DatabaseApi.java
@@ -27,7 +27,7 @@ import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.trove.v1.binders.BindCreateDatabaseToJson;
 import org.jclouds.openstack.trove.v1.functions.ParseDatabaseListForUser;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/FlavorApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/FlavorApi.java b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/FlavorApi.java
index b71a570..904f2a3 100644
--- a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/FlavorApi.java
+++ b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/FlavorApi.java
@@ -25,7 +25,7 @@ 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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.trove.v1.domain.Flavor;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/InstanceApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/InstanceApi.java b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/InstanceApi.java
index f64c75d..443b02d 100644
--- a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/InstanceApi.java
+++ b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/InstanceApi.java
@@ -29,7 +29,7 @@ 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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.trove.v1.binders.BindCreateInstanceToJson;
 import org.jclouds.openstack.trove.v1.domain.Instance;
 import org.jclouds.openstack.trove.v1.functions.ParsePasswordFromRootedInstance;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/UserApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/UserApi.java b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/UserApi.java
index 97449a4..3753c54 100644
--- a/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/UserApi.java
+++ b/apis/openstack-trove/src/main/java/org/jclouds/openstack/trove/v1/features/UserApi.java
@@ -18,6 +18,7 @@ package org.jclouds.openstack.trove.v1.features;
 
 import java.util.List;
 import java.util.Set;
+
 import javax.inject.Named;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -27,11 +28,12 @@ import javax.ws.rs.PUT;
 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.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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.trove.v1.binders.BindCreateUserToJson;
 import org.jclouds.openstack.trove.v1.binders.BindGrantUserToJson;
 import org.jclouds.openstack.trove.v1.domain.User;
@@ -44,6 +46,7 @@ import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.ResponseParser;
 import org.jclouds.rest.annotations.SelectJson;
 import org.jclouds.rest.annotations.SkipEncoding;
+
 import com.google.common.collect.FluentIterable;
 
 /**

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiExpectTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiExpectTest.java b/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiExpectTest.java
index df6b0bc..3284038 100644
--- a/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiExpectTest.java
+++ b/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiExpectTest.java
@@ -72,7 +72,7 @@ public class FlavorApiExpectTest extends BaseTroveApiExpectTest {
       HttpResponse.builder().statusCode(200).payload(payloadFromResource("/flavor_list.json")).build() );
       FlavorApi api = troveApi.getFlavorApi("RegionOne");
 
-      Set<? extends Flavor> flavors = api.list(troveApi.getCurrentTenantId().get().getId() ).toSet();
+      Set<? extends Flavor> flavors = api.list(troveApi.getCurrentTenantId().get()).toSet();
       Flavor flavor = flavors.iterator().next();
       assertEquals(flavor.getName(), "512MB Instance");
       assertEquals(flavor.getId(), 1);

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiLiveTest.java b/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiLiveTest.java
index 2f2ec40..50201da 100644
--- a/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiLiveTest.java
+++ b/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/features/FlavorApiLiveTest.java
@@ -45,7 +45,7 @@ public class FlavorApiLiveTest extends BaseTroveApiLiveTest {
         for (String region : api.getConfiguredRegions()) {
             FlavorApi flavorApi = api.getFlavorApi(region);
 
-            FluentIterable<Flavor> response = flavorApi.list( api.getCurrentTenantId().get().getId() ); // tenant id, but referred to as account id.
+            FluentIterable<Flavor> response = flavorApi.list( api.getCurrentTenantId().get()); // tenant id, but referred to as account id.
             for (Flavor flavor : response) {
                 checkFlavor(flavor);
             }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/internal/BaseTroveApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/internal/BaseTroveApiLiveTest.java b/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/internal/BaseTroveApiLiveTest.java
index 03df219..d38e973 100644
--- a/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/internal/BaseTroveApiLiveTest.java
+++ b/apis/openstack-trove/src/test/java/org/jclouds/openstack/trove/v1/internal/BaseTroveApiLiveTest.java
@@ -19,7 +19,7 @@ package org.jclouds.openstack.trove.v1.internal;
 import java.util.Properties;
 
 import org.jclouds.apis.BaseApiLiveTest;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.openstack.trove.v1.TroveApi;
 
 /**

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApi.java b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApi.java
index 651d6b7..e8b8f8f 100644
--- a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApi.java
+++ b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApi.java
@@ -28,7 +28,7 @@ import javax.ws.rs.PathParam;
 
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
 import org.jclouds.rackspace.clouddns.v1.domain.Job;
 import org.jclouds.rackspace.clouddns.v1.features.DomainApi;
@@ -36,6 +36,7 @@ import org.jclouds.rackspace.clouddns.v1.features.LimitApi;
 import org.jclouds.rackspace.clouddns.v1.features.RecordApi;
 import org.jclouds.rackspace.clouddns.v1.features.ReverseDNSApi;
 import org.jclouds.rackspace.clouddns.v1.functions.ParseJob;
+import org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates;
 import org.jclouds.rest.annotations.Delegate;
 import org.jclouds.rest.annotations.Endpoint;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApiMetadata.java b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApiMetadata.java
index 55ea21d..c06aab8 100644
--- a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApiMetadata.java
+++ b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/CloudDNSApiMetadata.java
@@ -16,8 +16,9 @@
  */
 package org.jclouds.rackspace.clouddns.v1;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 import static org.jclouds.rackspace.cloudidentity.v2_0.ServiceType.DNS;
 import static org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes.API_KEY_CREDENTIALS;
 
@@ -25,9 +26,9 @@ import java.net.URI;
 import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ProviderModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.ProviderModule;
 import org.jclouds.rackspace.clouddns.v1.config.CloudDNSHttpApiModule;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rest.internal.BaseHttpApiMetadata;
 
@@ -58,6 +59,7 @@ public class CloudDNSApiMetadata extends BaseHttpApiMetadata<CloudDNSApi> {
       Properties properties = BaseHttpApiMetadata.defaultProperties();
       properties.setProperty(SERVICE_TYPE, DNS);
       properties.setProperty(CREDENTIAL_TYPE, API_KEY_CREDENTIALS);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       return properties;
    }
 
@@ -73,8 +75,8 @@ public class CloudDNSApiMetadata extends BaseHttpApiMetadata<CloudDNSApi> {
          .defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/")
          .defaultProperties(CloudDNSApiMetadata.defaultProperties())
          .defaultModules(ImmutableSet.<Class<? extends Module>> builder()
-                                     .add(CloudIdentityAuthenticationApiModule.class)
                                      .add(CloudIdentityAuthenticationModule.class)
+                                     .add(ServiceCatalogModule.class)
                                      .add(ProviderModule.class)
                                      .add(CloudDNSHttpApiModule.class)
                                      .build());

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/DomainApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/DomainApi.java b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/DomainApi.java
index 7634e01..7ae67f6 100644
--- a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/DomainApi.java
+++ b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/DomainApi.java
@@ -37,10 +37,11 @@ import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
 import org.jclouds.openstack.v2_0.options.PaginationOptions;
+import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
 import org.jclouds.rackspace.clouddns.v1.binders.FormatAndContentsToJSON;
 import org.jclouds.rackspace.clouddns.v1.binders.UpdateDomainsToJSON;
 import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
@@ -56,8 +57,8 @@ import org.jclouds.rackspace.clouddns.v1.functions.ParseDomains;
 import org.jclouds.rackspace.clouddns.v1.functions.ParseJob;
 import org.jclouds.rackspace.clouddns.v1.functions.ParseSubdomains;
 import org.jclouds.rackspace.clouddns.v1.functions.SubdomainsToPagedIterable;
+import org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates;
 import org.jclouds.rackspace.cloudidentity.v2_0.functions.DateParser;
-
 import org.jclouds.rest.annotations.BinderParam;
 import org.jclouds.rest.annotations.Endpoint;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/LimitApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/LimitApi.java b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/LimitApi.java
index 5160ce6..6e62054 100644
--- a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/LimitApi.java
+++ b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/LimitApi.java
@@ -22,7 +22,7 @@ import javax.ws.rs.GET;
 import javax.ws.rs.Path;
 import javax.ws.rs.core.MediaType;
 
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.domain.Limits;
 import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
 import org.jclouds.rest.annotations.Endpoint;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/RecordApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/RecordApi.java b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/RecordApi.java
index bbc37a3..9752b96 100644
--- a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/RecordApi.java
+++ b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/RecordApi.java
@@ -35,10 +35,11 @@ import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.domain.PaginatedCollection;
 import org.jclouds.openstack.v2_0.options.PaginationOptions;
+import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
 import org.jclouds.rackspace.clouddns.v1.binders.UpdateRecordsToJSON;
 import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
 import org.jclouds.rackspace.clouddns.v1.domain.Job;
@@ -49,6 +50,7 @@ import org.jclouds.rackspace.clouddns.v1.functions.ParseOnlyRecord;
 import org.jclouds.rackspace.clouddns.v1.functions.ParseRecord;
 import org.jclouds.rackspace.clouddns.v1.functions.ParseRecords;
 import org.jclouds.rackspace.clouddns.v1.functions.RecordsToPagedIterable;
+import org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates;
 import org.jclouds.rest.annotations.BinderParam;
 import org.jclouds.rest.annotations.Endpoint;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/ReverseDNSApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/ReverseDNSApi.java b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/ReverseDNSApi.java
index df6860d..4b2aa09 100644
--- a/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/ReverseDNSApi.java
+++ b/apis/rackspace-clouddns/src/main/java/org/jclouds/rackspace/clouddns/v1/features/ReverseDNSApi.java
@@ -36,7 +36,8 @@ import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.Fallbacks.VoidOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
+import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
 import org.jclouds.rackspace.clouddns.v1.binders.CreateReverseDNSToJSON;
 import org.jclouds.rackspace.clouddns.v1.binders.UpdateReverseDNSToJSON;
 import org.jclouds.rackspace.clouddns.v1.config.CloudDNS;
@@ -47,6 +48,7 @@ import org.jclouds.rackspace.clouddns.v1.functions.ParseJob;
 import org.jclouds.rackspace.clouddns.v1.functions.ParseRecord;
 import org.jclouds.rackspace.clouddns.v1.functions.ParseRecords;
 import org.jclouds.rackspace.clouddns.v1.functions.RecordsToPagedIterable;
+import org.jclouds.rackspace.clouddns.v1.predicates.JobPredicates;
 import org.jclouds.rest.annotations.Endpoint;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.MapBinder;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-clouddns/src/test/java/org/jclouds/rackspace/clouddns/v1/internal/BaseCloudDNSApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-clouddns/src/test/java/org/jclouds/rackspace/clouddns/v1/internal/BaseCloudDNSApiLiveTest.java b/apis/rackspace-clouddns/src/test/java/org/jclouds/rackspace/clouddns/v1/internal/BaseCloudDNSApiLiveTest.java
index e2ffd43..58569b1 100644
--- a/apis/rackspace-clouddns/src/test/java/org/jclouds/rackspace/clouddns/v1/internal/BaseCloudDNSApiLiveTest.java
+++ b/apis/rackspace-clouddns/src/test/java/org/jclouds/rackspace/clouddns/v1/internal/BaseCloudDNSApiLiveTest.java
@@ -19,7 +19,7 @@ package org.jclouds.rackspace.clouddns.v1.internal;
 import java.util.Properties;
 
 import org.jclouds.apis.BaseApiLiveTest;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.rackspace.clouddns.v1.CloudDNSApi;
 
 public class BaseCloudDNSApiLiveTest extends BaseApiLiveTest<CloudDNSApi> {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadata.java b/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadata.java
index 3055678..19a0532 100644
--- a/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadata.java
+++ b/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/CloudFilesApiMetadata.java
@@ -16,15 +16,17 @@
  */
 package org.jclouds.rackspace.cloudfiles.v1;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.KEYSTONE_VERSION;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 import static org.jclouds.reflect.Reflection2.typeToken;
 
 import java.net.URI;
 import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.RegionModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
 import org.jclouds.openstack.swift.v1.SwiftApiMetadata;
 import org.jclouds.openstack.swift.v1.blobstore.RegionScopedBlobStoreContext;
 import org.jclouds.openstack.swift.v1.blobstore.config.SignUsingTemporaryUrls;
@@ -32,7 +34,6 @@ import org.jclouds.openstack.swift.v1.blobstore.config.SwiftBlobStoreContextModu
 import org.jclouds.openstack.swift.v1.config.SwiftTypeAdapters;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.rackspace.cloudfiles.v1.config.CloudFilesHttpApiModule;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 import org.jclouds.rest.internal.BaseHttpApiMetadata;
@@ -63,6 +64,7 @@ public class CloudFilesApiMetadata extends BaseHttpApiMetadata<CloudFilesApi> {
    public static Properties defaultProperties() {
       Properties properties = SwiftApiMetadata.defaultProperties();
       properties.setProperty(CREDENTIAL_TYPE, CloudIdentityCredentialTypes.API_KEY_CREDENTIALS);
+      properties.setProperty(KEYSTONE_VERSION, "2");
       properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE);
       return properties;
    }
@@ -81,8 +83,8 @@ public class CloudFilesApiMetadata extends BaseHttpApiMetadata<CloudFilesApi> {
          .defaultProperties(CloudFilesApiMetadata.defaultProperties())
          .view(typeToken(RegionScopedBlobStoreContext.class))
          .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                     .add(CloudIdentityAuthenticationApiModule.class)
                                      .add(CloudIdentityAuthenticationModule.class)
+                                     .add(ServiceCatalogModule.class)
                                      .add(RegionModule.class)
                                      .add(SwiftTypeAdapters.class)
                                      .add(CloudFilesHttpApiModule.class)

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/features/CDNApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/features/CDNApi.java b/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/features/CDNApi.java
index e88626f..8dd7c6c 100644
--- a/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/features/CDNApi.java
+++ b/apis/rackspace-cloudfiles/src/main/java/org/jclouds/rackspace/cloudfiles/v1/features/CDNApi.java
@@ -38,7 +38,7 @@ 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.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rackspace.cloudfiles.v1.binders.BindCDNPurgeEmailAddressesToHeaders;
 import org.jclouds.rackspace.cloudfiles.v1.domain.CDNContainer;
 import org.jclouds.rackspace.cloudfiles.v1.functions.ParseCDNContainerFromHeaders;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityApiMetadata.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityApiMetadata.java
index 3636a6c..9cca309 100644
--- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityApiMetadata.java
+++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityApiMetadata.java
@@ -16,17 +16,17 @@
  */
 package org.jclouds.rackspace.cloudidentity.v2_0;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
 
 import java.net.URI;
 import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
+import org.jclouds.openstack.keystone.catalog.config.KeystoneAdminURLModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
 import org.jclouds.openstack.keystone.v2_0.KeystoneApiMetadata;
 import org.jclouds.openstack.keystone.v2_0.config.KeystoneHttpApiModule;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneHttpApiModule.KeystoneAdminURLModule;
 import org.jclouds.openstack.keystone.v2_0.config.KeystoneParserModule;
-import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationApiModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityAuthenticationModule;
 import org.jclouds.rackspace.cloudidentity.v2_0.config.CloudIdentityCredentialTypes;
 
@@ -70,8 +70,8 @@ public class CloudIdentityApiMetadata extends KeystoneApiMetadata {
          .defaultProperties(CloudIdentityApiMetadata.defaultProperties())
          .documentation(URI.create("http://docs.rackspace.com/auth/api/v2.0/auth-api-devguide/"))
          .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                     .add(CloudIdentityAuthenticationApiModule.class)
                                      .add(CloudIdentityAuthenticationModule.class)
+                                     .add(ServiceCatalogModule.class)
                                      .add(KeystoneAdminURLModule.class)
                                      .add(KeystoneParserModule.class)
                                      .add(KeystoneHttpApiModule.class).build());

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationApi.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationApi.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationApi.java
index cb19a97..66ec404 100644
--- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationApi.java
+++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/CloudIdentityAuthenticationApi.java
@@ -22,13 +22,12 @@ import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.core.MediaType;
 
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
+import org.jclouds.openstack.keystone.auth.AuthenticationApi;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
 import org.jclouds.openstack.keystone.v2_0.binders.BindAuthToJsonPayload;
 import org.jclouds.openstack.keystone.v2_0.domain.Access;
 import org.jclouds.rackspace.cloudidentity.v2_0.domain.ApiKeyCredentials;
 import org.jclouds.rest.annotations.MapBinder;
-import org.jclouds.rest.annotations.PayloadParam;
 import org.jclouds.rest.annotations.SelectJson;
 
 /**
@@ -47,18 +46,6 @@ public interface CloudIdentityAuthenticationApi extends AuthenticationApi {
    @POST
    @SelectJson("access")
    @MapBinder(BindAuthToJsonPayload.class)
-   Access authenticateWithTenantNameAndCredentials(@Nullable @PayloadParam("tenantName") String tenantName,
-         ApiKeyCredentials apiKeyCredentials);
+   Access authenticateApiKey(TenantAndCredentials<ApiKeyCredentials> credentials);
 
-   /**
-    * Authenticate to generate a token.
-    *
-    * @return access with token
-    */
-   @Named("authenticate")
-   @POST
-   @SelectJson("access")
-   @MapBinder(BindAuthToJsonPayload.class)
-   Access authenticateWithTenantIdAndCredentials(@Nullable @PayloadParam("tenantId") String tenantId,
-         ApiKeyCredentials apiKeyCredentials);
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationApiModule.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationApiModule.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationApiModule.java
deleted file mode 100644
index d3f0ec1..0000000
--- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationApiModule.java
+++ /dev/null
@@ -1,39 +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.rackspace.cloudidentity.v2_0.config;
-
-import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
-
-import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
-import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityAuthenticationApi;
-
-import com.google.inject.AbstractModule;
-import com.google.inject.Provides;
-
-public class CloudIdentityAuthenticationApiModule extends AbstractModule  {
-
-   @Override
-   protected void configure() {
-      // AuthenticationApi is used directly for filters and retry handlers, so let's bind it explicitly
-      bindHttpApi(binder(), CloudIdentityAuthenticationApi.class);
-   }
-
-   @Provides
-   private AuthenticationApi provideAuthenticationApi(CloudIdentityAuthenticationApi in){
-      return in;
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationModule.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationModule.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationModule.java
index 88a51fa..655537d 100644
--- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationModule.java
+++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityAuthenticationModule.java
@@ -16,25 +16,44 @@
  */
 package org.jclouds.rackspace.cloudidentity.v2_0.config;
 
+import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
+
 import java.util.Map;
 
 import org.jclouds.domain.Credentials;
-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.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.functions.AuthenticatePasswordCredentials;
+import org.jclouds.openstack.keystone.auth.AuthenticationApi;
+import org.jclouds.openstack.keystone.auth.config.AuthenticationModule;
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.auth.functions.AuthenticatePasswordCredentials;
+import org.jclouds.rackspace.cloudidentity.v2_0.CloudIdentityAuthenticationApi;
 import org.jclouds.rackspace.cloudidentity.v2_0.functions.AuthenticateApiKeyCredentials;
 
 import com.google.common.base.Function;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.collect.Maps;
 import com.google.inject.Injector;
 
-public class CloudIdentityAuthenticationModule extends KeystoneAuthenticationModule {
+public class CloudIdentityAuthenticationModule extends AuthenticationModule {
+
+   @Override
+   protected void configure() {
+      super.configure();
+      bindHttpApi(binder(), CloudIdentityAuthenticationApi.class);
+   }
+
+   @Override
+   protected Map<String, AuthenticationApi> authenticationApis(Injector i) {
+      Map<String, AuthenticationApi> authenticationApis = Maps.newHashMap();
+      authenticationApis.put("2", i.getInstance(CloudIdentityAuthenticationApi.class));
+      authenticationApis.put("3", i.getInstance(CloudIdentityAuthenticationApi.class));
+      return authenticationApis;
+   }
 
    @Override
-   protected Map<String, Function<Credentials, Access>> authenticationMethods(Injector i) {
-      Builder<Function<Credentials, Access>> fns = ImmutableSet.<Function<Credentials, Access>> builder();
+   protected Map<String, Function<Credentials, AuthInfo>> authenticationMethods(Injector i) {
+      Builder<Function<Credentials, AuthInfo>> fns = ImmutableSet.<Function<Credentials, AuthInfo>> builder();
       fns.add(i.getInstance(AuthenticatePasswordCredentials.class));
       fns.add(i.getInstance(AuthenticateApiKeyCredentials.class));
       return CredentialTypes.indexByCredentialType(fns.build());

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityCredentialTypes.java
----------------------------------------------------------------------
diff --git a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityCredentialTypes.java b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityCredentialTypes.java
index 8313567..c96a192 100644
--- a/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityCredentialTypes.java
+++ b/apis/rackspace-cloudidentity/src/main/java/org/jclouds/rackspace/cloudidentity/v2_0/config/CloudIdentityCredentialTypes.java
@@ -16,7 +16,7 @@
  */
 package org.jclouds.rackspace.cloudidentity.v2_0.config;
 
-import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
 
 
 public class CloudIdentityCredentialTypes extends CredentialTypes {


[7/8] jclouds git commit: Initial work towards Keystone V3 authentication

Posted by na...@apache.org.
Initial work towards Keystone V3 authentication

Refactors the Keystone Authentication and Service Catalog classes to a
common model that can be used by V2 and V3 of Keystone. Each version
will have their own Authentication APIs and Service Catalog Suppliers,
and the higher level Keystone Authentication will transparently delegate
to the right API based on the keystone-version property.

OpenStack APIs will just have to define the default keystone-version
property they work with, and declare the generic Keystone Authentication
and Service Catalog modules.


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/7def8169
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/7def8169
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/7def8169

Branch: refs/heads/keystonev3
Commit: 7def8169b4063ae65b6d57324b98311a7f1115f5
Parents: 624367d
Author: Ignasi Barrera <na...@apache.org>
Authored: Tue Dec 5 17:13:31 2017 +0100
Committer: Ignasi Barrera <na...@apache.org>
Committed: Thu Dec 7 23:40:58 2017 +0100

----------------------------------------------------------------------
 .../openstack/cinder/v1/CinderApiMetadata.java  |  18 +-
 .../v1/extensions/AvailabilityZoneApi.java      |   2 +-
 .../openstack/cinder/v1/features/QuotaApi.java  |   2 +-
 .../cinder/v1/features/SnapshotApi.java         |   2 +-
 .../openstack/cinder/v1/features/VolumeApi.java |   2 +-
 .../cinder/v1/features/VolumeTypeApi.java       |   2 +-
 .../v1/internal/BaseCinderApiLiveTest.java      |   2 +-
 apis/openstack-keystone/pom.xml                 |  21 ++
 .../openstack/keystone/auth/AuthHeaders.java    |  28 ++
 .../keystone/auth/AuthenticationApi.java        |  35 +++
 .../keystone/auth/config/Authentication.java    |  31 +++
 .../auth/config/AuthenticationModule.java       | 142 ++++++++++
 .../keystone/auth/config/CredentialType.java    |  38 +++
 .../keystone/auth/config/CredentialTypes.java   |  66 +++++
 .../auth/domain/ApiAccessKeyCredentials.java    |  51 ++++
 .../keystone/auth/domain/AuthInfo.java          |  25 ++
 .../auth/domain/PasswordCredentials.java        |  59 +++++
 .../auth/domain/TenantAndCredentials.java       |  50 ++++
 .../keystone/auth/domain/TokenCredentials.java  |  50 ++++
 .../auth/filters/AuthenticateRequest.java       |  48 ++++
 .../AuthenticateApiAccessKeyCredentials.java    |  51 ++++
 .../AuthenticatePasswordCredentials.java        |  50 ++++
 .../functions/AuthenticateTokenCredentials.java |  50 ++++
 .../auth/functions/BaseAuthenticator.java       |  88 +++++++
 .../keystone/auth/handlers/RetryOnRenew.java    | 121 +++++++++
 .../keystone/catalog/ServiceEndpoint.java       |  74 ++++++
 .../catalog/config/InternalUrlModule.java       |  35 +++
 .../catalog/config/KeystoneAdminURLModule.java  |  64 +++++
 .../catalog/config/ServiceCatalogModule.java    | 160 ++++++++++++
 .../AdminEndpointResolutionStrategy.java        |  27 ++
 .../keystone/catalog/functions/AdminURL.java    |  34 +++
 .../BaseEndpointResolutionStrategy.java         |  62 +++++
 .../keystone/catalog/functions/InternalURL.java |  34 +++
 .../catalog/functions/PublicURLOrInternal.java  |  66 +++++
 .../functions/ReturnRegionOrProvider.java       |  38 +++
 .../ServiceEndpointResolutionStrategy.java      |  35 +++
 .../functions/ServiceEndpointToRegion.java      |  27 ++
 ...ationIdToURIFromAccessForTypeAndVersion.java | 129 ++++++++++
 ...IdToAdminURIFromAccessForTypeAndVersion.java |  44 ++++
 .../suppliers/RegionIdToAdminURISupplier.java   |  37 +++
 ...egionIdToURIFromAccessForTypeAndVersion.java |  46 ++++
 .../keystone/config/KeystoneProperties.java     |  83 ++++++
 .../keystone/v2_0/AuthenticationApi.java        |  91 -------
 .../keystone/v2_0/KeystoneApiMetadata.java      |  18 +-
 .../keystone/v2_0/auth/V2AuthenticationApi.java |  68 +++++
 .../v2_0/binders/BindAuthToJsonPayload.java     |  66 +++--
 .../keystone/v2_0/catalog/V2ServiceCatalog.java | 105 ++++++++
 .../keystone/v2_0/config/Authentication.java    |  31 ---
 .../v2_0/config/AuthenticationApiModule.java    |  33 ---
 .../keystone/v2_0/config/CredentialType.java    |  38 ---
 .../keystone/v2_0/config/CredentialTypes.java   |  52 ----
 .../config/KeystoneAuthenticationModule.java    | 257 -------------------
 .../v2_0/config/KeystoneHttpApiModule.java      |  39 ---
 .../v2_0/config/KeystoneProperties.java         |  75 ------
 .../openstack/keystone/v2_0/domain/Access.java  |   8 +-
 .../v2_0/domain/ApiAccessKeyCredentials.java    | 140 ----------
 .../keystone/v2_0/domain/Endpoint.java          |   2 +-
 .../v2_0/domain/PasswordCredentials.java        | 140 ----------
 .../keystone/v2_0/extensions/RoleAdminApi.java  |   2 +-
 .../v2_0/extensions/ServiceAdminApi.java        |   2 +-
 .../v2_0/extensions/TenantAdminApi.java         |   2 +-
 .../keystone/v2_0/extensions/UserAdminApi.java  |   2 +-
 .../keystone/v2_0/features/ServiceApi.java      |   2 +-
 .../keystone/v2_0/features/TenantApi.java       |   2 +-
 .../keystone/v2_0/features/TokenApi.java        |   2 +-
 .../keystone/v2_0/features/UserApi.java         |   2 +-
 .../v2_0/filters/AuthenticateRequest.java       |  48 ----
 .../keystone/v2_0/functions/AdminURL.java       |  38 ---
 .../AuthenticateApiAccessKeyCredentials.java    |  60 -----
 .../AuthenticatePasswordCredentials.java        |  60 -----
 .../v2_0/functions/EndpointToRegion.java        |  27 --
 .../functions/EndpointToSupplierAdminURI.java   |  23 --
 .../v2_0/functions/EndpointToSupplierURI.java   |  29 ---
 .../keystone/v2_0/functions/InternalURL.java    |  43 ----
 .../functions/PublicURLOrInternalIfNull.java    |  39 ---
 .../functions/RegionToAdminEndpointURI.java     |  49 ----
 .../v2_0/functions/ReturnRegionOrProvider.java  |  40 ---
 .../functions/internal/BaseAuthenticator.java   |  97 -------
 .../keystone/v2_0/handlers/RetryOnRenew.java    | 121 ---------
 ...ationIdToURIFromAccessForTypeAndVersion.java | 208 ---------------
 ...IdToAdminURIFromAccessForTypeAndVersion.java |  42 ---
 .../suppliers/RegionIdToAdminURISupplier.java   |  45 ----
 ...egionIdToURIFromAccessForTypeAndVersion.java |  44 ----
 .../ZoneIdToURIFromAccessForTypeAndVersion.java |  47 ----
 .../openstack/keystone/v3/KeystoneApi.java      |  35 +++
 .../keystone/v3/KeystoneApiMetadata.java        |  98 +++++++
 .../keystone/v3/auth/V3AuthenticationApi.java   |  60 +++++
 .../v3/binders/BindAuthToJsonPayload.java       |  64 +++++
 .../binders/BindPasswordAuthToJsonPayload.java  |  50 ++++
 .../v3/binders/BindTokenAuthToJsonPayload.java  |  45 ++++
 .../keystone/v3/catalog/V3ServiceCatalog.java   |  63 +++++
 .../openstack/keystone/v3/domain/Auth.java      |  94 +++++++
 .../openstack/keystone/v3/domain/Catalog.java   |  48 ++++
 .../openstack/keystone/v3/domain/Endpoint.java  |  52 ++++
 .../openstack/keystone/v3/domain/Link.java      |  36 +++
 .../openstack/keystone/v3/domain/Region.java    |  46 ++++
 .../openstack/keystone/v3/domain/Token.java     | 103 ++++++++
 .../openstack/keystone/v3/domain/User.java      |  57 ++++
 .../keystone/v3/features/TokenApi.java          | 132 ++++++++++
 .../keystone/v3/parsers/ParseToken.java         |  41 +++
 .../v2_0/config/InternalUrlModule.java          |  35 ---
 .../openstack/v2_0/features/ExtensionApi.java   |   2 +-
 .../openstack/v2_0/reference/AuthHeaders.java   |  28 --
 .../auth/config/CredentialTypesTest.java        |  51 ++++
 .../auth/config/ProviderModuleExpectTest.java   | 180 +++++++++++++
 .../auth/handlers/RetryOnRenewTest.java         | 131 ++++++++++
 ...nIdToURIFromAccessForTypeAndVersionTest.java | 139 ++++++++++
 ...AdminURIFromAccessForTypeAndVersionTest.java | 125 +++++++++
 ...nIdToURIFromAccessForTypeAndVersionTest.java | 128 +++++++++
 .../catalog/functions/AdminURLTest.java         |  54 ++++
 .../catalog/functions/InternalURLTest.java      |  42 +++
 .../functions/PublicURLOrInternalTest.java      |  54 ++++
 .../functions/ReturnRegionOrProviderTest.java   |  45 ++++
 .../v2_0/config/CredentialTypesTest.java        |  49 ----
 .../v2_0/config/ProviderModuleExpectTest.java   | 176 -------------
 .../v2_0/features/TokenApiLiveTest.java         |   2 +-
 .../keystone/v2_0/functions/AdminURLTest.java   |  45 ----
 .../v2_0/functions/InternalURLTest.java         |  39 ---
 .../PublicURLOrInternalIfNullTest.java          |  46 ----
 .../functions/ReturnRegionOrProviderTest.java   |  44 ----
 .../v2_0/handlers/RetryOnRenewTest.java         | 131 ----------
 .../v2_0/internal/BaseKeystoneApiLiveTest.java  |   2 +-
 .../internal/BaseKeystoneRestApiExpectTest.java |   2 +-
 ...nIdToURIFromAccessForTypeAndVersionTest.java | 126 ---------
 ...AdminURIFromAccessForTypeAndVersionTest.java | 113 --------
 ...nIdToURIFromAccessForTypeAndVersionTest.java | 118 ---------
 ...eIdToURIFromAccessForTypeAndVersionTest.java | 113 --------
 .../openstack/nova/v2_0/NovaApiMetadata.java    |  18 +-
 .../v2_0/extensions/AttachInterfaceApi.java     |   2 +-
 .../v2_0/extensions/AvailabilityZoneApi.java    |   2 +-
 .../nova/v2_0/extensions/ConsolesApi.java       |   2 +-
 .../v2_0/extensions/FlavorExtraSpecsApi.java    |   2 +-
 .../nova/v2_0/extensions/FloatingIPApi.java     |   2 +-
 .../nova/v2_0/extensions/FloatingIPPoolApi.java |   2 +-
 .../v2_0/extensions/HostAdministrationApi.java  |   2 +-
 .../nova/v2_0/extensions/HostAggregateApi.java  |   2 +-
 .../nova/v2_0/extensions/HypervisorApi.java     |   2 +-
 .../nova/v2_0/extensions/KeyPairApi.java        |   2 +-
 .../nova/v2_0/extensions/QuotaApi.java          |   2 +-
 .../nova/v2_0/extensions/SecurityGroupApi.java  |   2 +-
 .../nova/v2_0/extensions/ServerAdminApi.java    |   2 +-
 .../extensions/ServerWithSecurityGroupsApi.java |   2 +-
 .../v2_0/extensions/SimpleTenantUsageApi.java   |   2 +-
 .../v2_0/extensions/VirtualInterfaceApi.java    |   2 +-
 .../nova/v2_0/extensions/VolumeApi.java         |   2 +-
 .../v2_0/extensions/VolumeAttachmentApi.java    |   2 +-
 .../nova/v2_0/extensions/VolumeTypeApi.java     |   2 +-
 .../openstack/nova/v2_0/features/FlavorApi.java |   2 +-
 .../openstack/nova/v2_0/features/ImageApi.java  |   2 +-
 .../openstack/nova/v2_0/features/ServerApi.java |   2 +-
 ...tKeyAndTenantIdAuthenticationExpectTest.java |   2 +-
 ...KeyAndSecretKeyAuthenticationExpectTest.java |   2 +-
 .../v2_0/PasswordAuthenticationExpectTest.java  |   2 +-
 ...dAuthenticationWithTenantNameExpectTest.java |   2 +-
 .../compute/NovaComputeServiceLiveTest.java     |   2 +-
 .../v2_0/functions/InternalURLLiveTest.java     |   2 +-
 .../nova/v2_0/internal/BaseNovaApiLiveTest.java |   2 +-
 .../openstack/swift/v1/SwiftApiMetadata.java    |  19 +-
 .../v1/config/SwiftAuthenticationModule.java    |  29 ++-
 .../openstack/swift/v1/features/AccountApi.java |   2 +-
 .../openstack/swift/v1/features/BulkApi.java    |   2 +-
 .../swift/v1/features/ContainerApi.java         |   2 +-
 .../v1/features/DynamicLargeObjectApi.java      |   2 +-
 .../openstack/swift/v1/features/ObjectApi.java  |   4 +-
 .../swift/v1/features/StaticLargeObjectApi.java |   3 +-
 .../openstack/swift/v1/TempAuthMockTest.java    |   2 +-
 .../RegionScopedBlobStoreContextLiveTest.java   |   2 +-
 ...ionScopedSwiftBlobStoreParallelLiveTest.java |   2 +-
 .../SwiftBlobIntegrationLiveTest.java           |   2 +-
 .../integration/SwiftBlobLiveTest.java          |   2 +-
 .../integration/SwiftBlobSignerLiveTest.java    |   2 +-
 .../SwiftContainerIntegrationLiveTest.java      |   4 +-
 .../integration/SwiftContainerLiveTest.java     |   2 +-
 .../SwiftServiceIntegrationLiveTest.java        |   2 +-
 .../swift/v1/internal/BaseSwiftApiLiveTest.java |   2 +-
 .../jclouds/openstack/trove/v1/TroveApi.java    |   3 +-
 .../openstack/trove/v1/TroveApiMetadata.java    |  18 +-
 .../trove/v1/config/TroveHttpApiModule.java     |  20 +-
 .../trove/v1/features/DatabaseApi.java          |   2 +-
 .../openstack/trove/v1/features/FlavorApi.java  |   2 +-
 .../trove/v1/features/InstanceApi.java          |   2 +-
 .../openstack/trove/v1/features/UserApi.java    |   5 +-
 .../trove/v1/features/FlavorApiExpectTest.java  |   2 +-
 .../trove/v1/features/FlavorApiLiveTest.java    |   2 +-
 .../trove/v1/internal/BaseTroveApiLiveTest.java |   2 +-
 .../rackspace/clouddns/v1/CloudDNSApi.java      |   3 +-
 .../clouddns/v1/CloudDNSApiMetadata.java        |  12 +-
 .../clouddns/v1/features/DomainApi.java         |   5 +-
 .../clouddns/v1/features/LimitApi.java          |   2 +-
 .../clouddns/v1/features/RecordApi.java         |   4 +-
 .../clouddns/v1/features/ReverseDNSApi.java     |   4 +-
 .../v1/internal/BaseCloudDNSApiLiveTest.java    |   2 +-
 .../cloudfiles/v1/CloudFilesApiMetadata.java    |  12 +-
 .../cloudfiles/v1/features/CDNApi.java          |   2 +-
 .../v2_0/CloudIdentityApiMetadata.java          |   8 +-
 .../v2_0/CloudIdentityAuthenticationApi.java    |  19 +-
 .../CloudIdentityAuthenticationApiModule.java   |  39 ---
 .../CloudIdentityAuthenticationModule.java      |  33 ++-
 .../config/CloudIdentityCredentialTypes.java    |   2 +-
 .../v2_0/domain/ApiKeyCredentials.java          |   4 +-
 .../AuthenticateApiKeyCredentials.java          |  26 +-
 .../v1/CloudLoadBalancersApiMetadata.java       |  12 +-
 .../v1/features/AccessRuleApi.java              |   2 +-
 .../v1/features/ConnectionApi.java              |   2 +-
 .../v1/features/ContentCachingApi.java          |   2 +-
 .../v1/features/ErrorPageApi.java               |   2 +-
 .../v1/features/HealthMonitorApi.java           |   2 +-
 .../v1/features/LoadBalancerApi.java            |   2 +-
 .../cloudloadbalancers/v1/features/NodeApi.java |   2 +-
 .../v1/features/ReportApi.java                  |   2 +-
 .../v1/features/SSLTerminationApi.java          |   2 +-
 .../v1/features/SessionPersistenceApi.java      |   2 +-
 .../v1/features/VirtualIPApi.java               |   2 +-
 .../BaseCloudLoadBalancersApiLiveTest.java      |   2 +-
 .../uk/CloudBlockStorageUKProviderMetadata.java |  10 +-
 .../us/CloudBlockStorageUSProviderMetadata.java |  10 +-
 .../uk/CloudDatabasesUKProviderMetadata.java    |  12 +-
 .../us/CloudDatabasesUSProviderMetadata.java    |  12 +-
 .../uk/CloudFilesUKProviderMetadata.java        |  12 +-
 .../us/CloudFilesUSProviderMetadata.java        |  14 +-
 .../uk/CloudServersUKProviderMetadata.java      | 135 +++++-----
 .../us/CloudServersUSProviderMetadata.java      |  12 +-
 222 files changed, 4566 insertions(+), 3395 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/CinderApiMetadata.java
----------------------------------------------------------------------
diff --git a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/CinderApiMetadata.java b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/CinderApiMetadata.java
index fc9ac76..3e37235 100644
--- a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/CinderApiMetadata.java
+++ b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/CinderApiMetadata.java
@@ -16,8 +16,8 @@
  */
 package org.jclouds.openstack.cinder.v1;
 
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.SERVICE_TYPE;
 
 import java.net.URI;
 import java.util.Properties;
@@ -25,10 +25,11 @@ import java.util.Properties;
 import org.jclouds.apis.ApiMetadata;
 import org.jclouds.openstack.cinder.v1.config.CinderHttpApiModule;
 import org.jclouds.openstack.cinder.v1.config.CinderParserModule;
-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.RegionModule;
+import org.jclouds.openstack.keystone.auth.config.AuthenticationModule;
+import org.jclouds.openstack.keystone.auth.config.CredentialTypes;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule;
+import org.jclouds.openstack.keystone.catalog.config.ServiceCatalogModule.RegionModule;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.rest.internal.BaseHttpApiMetadata;
 
@@ -58,6 +59,7 @@ public class CinderApiMetadata extends BaseHttpApiMetadata<CinderApi> {
    public static Properties defaultProperties() {
       Properties properties = BaseHttpApiMetadata.defaultProperties();
       properties.setProperty(SERVICE_TYPE, ServiceType.BLOCK_STORAGE);
+      properties.setProperty(KeystoneProperties.KEYSTONE_VERSION, "2");
       properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
       return properties;
    }
@@ -75,8 +77,8 @@ public class CinderApiMetadata extends BaseHttpApiMetadata<CinderApi> {
          .defaultEndpoint("http://localhost:5000/v2.0/")
          .defaultProperties(CinderApiMetadata.defaultProperties())
          .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
-                                     .add(AuthenticationApiModule.class)
-                                     .add(KeystoneAuthenticationModule.class)
+                                     .add(AuthenticationModule.class)
+                                     .add(ServiceCatalogModule.class)
                                      .add(RegionModule.class)
                                      .add(CinderParserModule.class)
                                      .add(CinderHttpApiModule.class)

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/extensions/AvailabilityZoneApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/extensions/AvailabilityZoneApi.java b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/extensions/AvailabilityZoneApi.java
index 4b2abdb..1594419 100644
--- a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/extensions/AvailabilityZoneApi.java
+++ b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/extensions/AvailabilityZoneApi.java
@@ -21,7 +21,7 @@ import com.google.common.annotations.Beta;
 import com.google.common.collect.FluentIterable;
 import org.jclouds.Fallbacks;
 import org.jclouds.openstack.cinder.v1.domain.AvailabilityZone;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/QuotaApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/QuotaApi.java b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/QuotaApi.java
index e8c39f9..14fa57c 100644
--- a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/QuotaApi.java
+++ b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/QuotaApi.java
@@ -26,7 +26,7 @@ import javax.ws.rs.core.MediaType;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.openstack.cinder.v1.domain.VolumeQuota;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.SelectJson;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/SnapshotApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/SnapshotApi.java b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/SnapshotApi.java
index 4c5be5b..28c3e8b 100644
--- a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/SnapshotApi.java
+++ b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/SnapshotApi.java
@@ -32,7 +32,7 @@ import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.openstack.cinder.v1.domain.Snapshot;
 import org.jclouds.openstack.cinder.v1.options.CreateSnapshotOptions;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.MapBinder;
 import org.jclouds.rest.annotations.PayloadParam;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeApi.java b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeApi.java
index c6d4d54..c9f9820 100644
--- a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeApi.java
+++ b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeApi.java
@@ -32,7 +32,7 @@ import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.openstack.cinder.v1.domain.Volume;
 import org.jclouds.openstack.cinder.v1.options.CreateVolumeOptions;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.MapBinder;
 import org.jclouds.rest.annotations.PayloadParam;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeTypeApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeTypeApi.java b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeTypeApi.java
index da59d8b..2ee062e 100644
--- a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeTypeApi.java
+++ b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/features/VolumeTypeApi.java
@@ -27,7 +27,7 @@ import org.jclouds.Fallbacks.EmptyFluentIterableOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.openstack.cinder.v1.domain.VolumeType;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.SelectJson;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/internal/BaseCinderApiLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/internal/BaseCinderApiLiveTest.java b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/internal/BaseCinderApiLiveTest.java
index 23c4702..88397bc 100644
--- a/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/internal/BaseCinderApiLiveTest.java
+++ b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/internal/BaseCinderApiLiveTest.java
@@ -20,7 +20,7 @@ import java.util.Properties;
 
 import org.jclouds.apis.BaseApiLiveTest;
 import org.jclouds.openstack.cinder.v1.CinderApi;
-import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
 
 /**
  * Tests behavior of CinderApi

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/pom.xml
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/pom.xml b/apis/openstack-keystone/pom.xml
index a4a2e7a..b0f8cf8 100644
--- a/apis/openstack-keystone/pom.xml
+++ b/apis/openstack-keystone/pom.xml
@@ -84,7 +84,28 @@
       <artifactId>auto-service</artifactId>
       <optional>true</optional>
     </dependency>
+    <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value</artifactId>
+      <scope>provided</scope>
+    </dependency>
   </dependencies>
+  
+  <build>
+    <plugins>
+    <!-- Disabling error-prone compiler due to: https://github.com/google/error-prone/issues/711
+         The fix is only available in error-prone versions that do not support Java 7 -->
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <inherited>false</inherited>
+        <configuration>
+          <source>${maven.compile.source}</source>
+          <target>${maven.compile.target}</target>
+          <encoding>${project.build.sourceEncoding}</encoding>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
 
   <profiles>
     <profile>

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/AuthHeaders.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/AuthHeaders.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/AuthHeaders.java
new file mode 100644
index 0000000..c6d6b27
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/AuthHeaders.java
@@ -0,0 +1,28 @@
+/*
+ * 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.keystone.auth;
+
+public final class AuthHeaders {
+
+   public static final String AUTH_USER = "X-Auth-User";
+   public static final String AUTH_KEY = "X-Auth-Key";
+   public static final String AUTH_TOKEN = "X-Auth-Token";
+
+   private AuthHeaders() {
+      throw new AssertionError("intentionally unimplemented");
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/AuthenticationApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/AuthenticationApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/AuthenticationApi.java
new file mode 100644
index 0000000..ea66e34
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/AuthenticationApi.java
@@ -0,0 +1,35 @@
+/*
+ * 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.keystone.auth;
+
+import org.jclouds.openstack.keystone.auth.domain.ApiAccessKeyCredentials;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+import org.jclouds.openstack.keystone.auth.domain.PasswordCredentials;
+import org.jclouds.openstack.keystone.auth.domain.TokenCredentials;
+
+/**
+ * Authentication methods to be implemented to all Keystone authentication APIs.
+ */
+public interface AuthenticationApi {
+
+   AuthInfo authenticatePassword(TenantAndCredentials<PasswordCredentials> credentials);
+
+   AuthInfo authenticateAccessKey(TenantAndCredentials<ApiAccessKeyCredentials> credentials);
+
+   AuthInfo authenticateToken(TenantAndCredentials<TokenCredentials> credentials);
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/Authentication.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/Authentication.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/Authentication.java
new file mode 100644
index 0000000..b4d59f5
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/Authentication.java
@@ -0,0 +1,31 @@
+/*
+ * 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.keystone.auth.config;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface Authentication {
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/AuthenticationModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/AuthenticationModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/AuthenticationModule.java
new file mode 100644
index 0000000..dbd9743
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/AuthenticationModule.java
@@ -0,0 +1,142 @@
+/*
+ * 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.keystone.auth.config;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.jclouds.rest.config.BinderUtils.bindHttpApi;
+
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.domain.Credentials;
+import org.jclouds.http.HttpRetryHandler;
+import org.jclouds.http.annotation.ClientError;
+import org.jclouds.location.Provider;
+import org.jclouds.openstack.keystone.auth.AuthenticationApi;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.auth.functions.AuthenticateApiAccessKeyCredentials;
+import org.jclouds.openstack.keystone.auth.functions.AuthenticatePasswordCredentials;
+import org.jclouds.openstack.keystone.auth.functions.AuthenticateTokenCredentials;
+import org.jclouds.openstack.keystone.auth.handlers.RetryOnRenew;
+import org.jclouds.openstack.keystone.config.KeystoneProperties;
+import org.jclouds.openstack.keystone.v2_0.auth.V2AuthenticationApi;
+import org.jclouds.openstack.keystone.v3.auth.V3AuthenticationApi;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.collect.Maps;
+import com.google.inject.AbstractModule;
+import com.google.inject.Injector;
+import com.google.inject.Provides;
+
+public class AuthenticationModule extends AbstractModule {
+
+   @Override
+   protected void configure() {
+      bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
+      bindHttpApi(binder(), V2AuthenticationApi.class);
+      bindHttpApi(binder(), V3AuthenticationApi.class);
+   }
+
+   @Provides
+   @Singleton
+   protected final AuthenticationApi provideAuthenticationApi(Injector i,
+         @Named(KeystoneProperties.KEYSTONE_VERSION) String keystoneVersion) {
+      return authenticationApis(i).get(keystoneVersion);
+   }
+
+   protected Map<String, AuthenticationApi> authenticationApis(Injector i) {
+      Map<String, AuthenticationApi> authenticationApis = Maps.newHashMap();
+      authenticationApis.put("2", i.getInstance(V2AuthenticationApi.class));
+      authenticationApis.put("3", i.getInstance(V3AuthenticationApi.class));
+      return authenticationApis;
+   }
+
+   /**
+    * borrowing concurrency code to ensure that caching takes place properly
+    */
+   @Provides
+   @Singleton
+   @Authentication
+   protected final Supplier<String> provideAuthenticationTokenCache(final Supplier<AuthInfo> supplier)
+         throws InterruptedException, ExecutionException, TimeoutException {
+      return new Supplier<String>() {
+         @Override
+         public String get() {
+            return supplier.get().getAuthToken();
+         }
+      };
+   }
+
+   @Provides
+   @Singleton
+   protected final Map<String, Function<Credentials, AuthInfo>> provideAuthenticationMethods(Injector i) {
+      return authenticationMethods(i);
+   }
+
+   protected Map<String, Function<Credentials, AuthInfo>> authenticationMethods(Injector i) {
+      Builder<Function<Credentials, AuthInfo>> fns = ImmutableSet.<Function<Credentials, AuthInfo>> builder();
+      fns.add(i.getInstance(AuthenticatePasswordCredentials.class));
+      fns.add(i.getInstance(AuthenticateApiAccessKeyCredentials.class));
+      fns.add(i.getInstance(AuthenticateTokenCredentials.class));
+      return CredentialTypes.indexByCredentialType(fns.build());
+   }
+
+   @Provides
+   @Singleton
+   protected final Function<Credentials, AuthInfo> authenticationMethodForCredentialType(
+         @Named(KeystoneProperties.CREDENTIAL_TYPE) String credentialType,
+         Map<String, Function<Credentials, AuthInfo>> authenticationMethods) {
+      checkArgument(authenticationMethods.containsKey(credentialType), "credential type %s not in supported list: %s",
+            credentialType, authenticationMethods.keySet());
+      return authenticationMethods.get(credentialType);
+   }
+
+   // TODO: what is the timeout of the session token? modify default accordingly
+   // PROPERTY_SESSION_INTERVAL is default to 60 seconds, but we have this here
+   // at 11 hours for now.
+   @Provides
+   @Singleton
+   public final LoadingCache<Credentials, AuthInfo> provideAccessCache(Function<Credentials, AuthInfo> getAccess) {
+      return CacheBuilder.newBuilder().expireAfterWrite(11, TimeUnit.HOURS).build(CacheLoader.from(getAccess));
+   }
+
+   // Temporary conversion of a cache to a supplier until there is a
+   // single-element cache
+   // http://code.google.com/p/guava-libraries/issues/detail?id=872
+   @Provides
+   @Singleton
+   protected final Supplier<AuthInfo> provideAccessSupplier(final LoadingCache<Credentials, AuthInfo> cache,
+         @Provider final Supplier<Credentials> creds) {
+      return new Supplier<AuthInfo>() {
+         @Override
+         public AuthInfo get() {
+            return cache.getUnchecked(creds.get());
+         }
+      };
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/CredentialType.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/CredentialType.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/CredentialType.java
new file mode 100644
index 0000000..171426f
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/CredentialType.java
@@ -0,0 +1,38 @@
+/*
+ * 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.keystone.auth.config;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * @see CredentialTypes
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface CredentialType {
+   /**
+    * @see CredentialTypes
+    * 
+    */
+   String value();
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/CredentialTypes.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/CredentialTypes.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/CredentialTypes.java
new file mode 100644
index 0000000..ed9764a
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/config/CredentialTypes.java
@@ -0,0 +1,66 @@
+/*
+ * 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.keystone.auth.config;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.util.Map;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+
+/**
+ * Configuration properties and constants used in Keystone connections.
+ */
+public class CredentialTypes {
+
+   public static final String API_ACCESS_KEY_CREDENTIALS = "apiAccessKeyCredentials";
+
+   public static final String PASSWORD_CREDENTIALS = "passwordCredentials";
+
+   public static final String TOKEN_CREDENTIALS = "tokenCredentials";
+
+   public static <T> String credentialTypeOf(T input) {
+      Class<?> authenticationType = input.getClass();
+      CredentialType credentialType = findCredentialType(authenticationType);
+      checkArgument(credentialType != null, "programming error: %s should have annotation %s", authenticationType,
+            CredentialType.class.getName());
+      return credentialType.value();
+   }
+
+   public static <T> Map<String, T> indexByCredentialType(Iterable<T> iterable) {
+      return Maps.uniqueIndex(iterable, new Function<T, String>() {
+
+         @Override
+         public String apply(T input) {
+            return credentialTypeOf(input);
+         }
+
+      });
+   }
+
+   /**
+    * Find an annotation in teh given class or their parents. We need this since
+    * AutoValue classes inherit the classes we define.
+    */
+   public static CredentialType findCredentialType(Class<?> input) {
+      if (input == null)
+         return null;
+      CredentialType ann = input.getAnnotation(CredentialType.class);
+      return ann != null ? ann : findCredentialType(input.getSuperclass());
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/ApiAccessKeyCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/ApiAccessKeyCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/ApiAccessKeyCredentials.java
new file mode 100644
index 0000000..c2e1e47
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/ApiAccessKeyCredentials.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.keystone.auth.domain;
+
+import static org.jclouds.openstack.keystone.auth.config.CredentialTypes.API_ACCESS_KEY_CREDENTIALS;
+
+import org.jclouds.openstack.keystone.auth.config.CredentialType;
+
+import com.google.auto.value.AutoValue;
+
+@CredentialType(API_ACCESS_KEY_CREDENTIALS)
+@AutoValue
+public abstract class ApiAccessKeyCredentials {
+
+   public abstract String accessKey();
+   public abstract String secretKey();
+
+   public static ApiAccessKeyCredentials create(String accessKey, String secretKey, String tenantId, String tenantName) {
+      return builder().accessKey(accessKey).secretKey(secretKey).build();
+   }
+
+   ApiAccessKeyCredentials() {
+
+   }
+
+   public static Builder builder() {
+      return new AutoValue_ApiAccessKeyCredentials.Builder();
+   }
+
+   @AutoValue.Builder
+   public abstract static class Builder {
+      public abstract Builder accessKey(String accessKey);
+      public abstract Builder secretKey(String secretKey);
+
+      public abstract ApiAccessKeyCredentials build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/AuthInfo.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/AuthInfo.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/AuthInfo.java
new file mode 100644
index 0000000..98e62ef
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/AuthInfo.java
@@ -0,0 +1,25 @@
+/*
+ * 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.keystone.auth.domain;
+
+/**
+ * Common interface for authentication objects.
+ */
+public interface AuthInfo {
+
+   String getAuthToken();
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/PasswordCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/PasswordCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/PasswordCredentials.java
new file mode 100644
index 0000000..d7a039c
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/PasswordCredentials.java
@@ -0,0 +1,59 @@
+/*
+ * 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.keystone.auth.domain;
+
+import static org.jclouds.openstack.keystone.auth.config.CredentialTypes.PASSWORD_CREDENTIALS;
+
+import org.jclouds.openstack.keystone.auth.config.CredentialType;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.base.MoreObjects;
+
+@CredentialType(PASSWORD_CREDENTIALS)
+@AutoValue
+public abstract class PasswordCredentials {
+
+   public abstract String username();
+   public abstract String password();
+
+   public static PasswordCredentials create(String username, String password, String tenantId, String tenantName) {
+      return builder().username(username).password(password).build();
+   }
+
+   PasswordCredentials() {
+
+   }
+   
+   @Override
+   public String toString() {
+      return MoreObjects.toStringHelper(this).add("username", username())
+            .add("password", password() == null ? null : "*****").toString();
+   }
+
+   public static Builder builder() {
+      return new AutoValue_PasswordCredentials.Builder();
+   }
+
+   @AutoValue.Builder
+   public abstract static class Builder {
+      public abstract Builder username(String username);
+      public abstract Builder password(String password);
+      
+      public abstract PasswordCredentials build();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TenantAndCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TenantAndCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TenantAndCredentials.java
new file mode 100644
index 0000000..5988c67
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TenantAndCredentials.java
@@ -0,0 +1,50 @@
+/*
+ * 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.keystone.auth.domain;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.auto.value.AutoValue;
+
+/**
+ * Keystone credentials with tenant. Configure the tenant properties to the
+ * configured context credentials.
+ */
+@AutoValue
+public abstract class TenantAndCredentials<T> {
+
+   @Nullable public abstract String tenantId();
+   @Nullable public abstract String tenantName();
+   public abstract T credentials();
+
+   TenantAndCredentials() {
+
+   }
+
+   public static <T> Builder<T> builder() {
+      return new AutoValue_TenantAndCredentials.Builder<T>();
+   }
+
+   @AutoValue.Builder
+   public abstract static class Builder<T> {
+      public abstract Builder<T> tenantId(String tenantId);
+      public abstract Builder<T> tenantName(String tenantName);
+      public abstract Builder<T> credentials(T credentials);
+
+      public abstract TenantAndCredentials<T> build();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TokenCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TokenCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TokenCredentials.java
new file mode 100644
index 0000000..7a4e0d3
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/domain/TokenCredentials.java
@@ -0,0 +1,50 @@
+/*
+ * 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.keystone.auth.domain;
+
+import static org.jclouds.openstack.keystone.auth.config.CredentialTypes.TOKEN_CREDENTIALS;
+
+import org.jclouds.openstack.keystone.auth.config.CredentialType;
+
+import com.google.auto.value.AutoValue;
+
+@CredentialType(TOKEN_CREDENTIALS)
+@AutoValue
+public abstract class TokenCredentials {
+
+   public abstract String id();
+
+   public static TokenCredentials create(String id, String secretKey, String tenantId, String tenantName) {
+      return builder().id(id).build();
+   }
+
+   TokenCredentials() {
+
+   }
+
+   public static Builder builder() {
+      return new AutoValue_TokenCredentials.Builder();
+   }
+
+   @AutoValue.Builder
+   public abstract static class Builder {
+      public abstract Builder id(String id);
+
+      public abstract TokenCredentials build();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/filters/AuthenticateRequest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/filters/AuthenticateRequest.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/filters/AuthenticateRequest.java
new file mode 100644
index 0000000..6ee125c
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/filters/AuthenticateRequest.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.keystone.auth.filters;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.http.HttpException;
+import org.jclouds.http.HttpRequest;
+import org.jclouds.http.HttpRequestFilter;
+import org.jclouds.openstack.keystone.auth.AuthHeaders;
+import org.jclouds.openstack.keystone.auth.config.Authentication;
+
+import com.google.common.base.Supplier;
+
+/**
+ * Signs the Keystone-based request. This will update the Authentication Token before 24 hours is up.
+ */
+@Singleton
+public class AuthenticateRequest implements HttpRequestFilter {
+
+   private final Supplier<String> authTokenProvider;
+
+   @Inject
+   AuthenticateRequest(@Authentication Supplier<String> authTokenProvider) {
+      this.authTokenProvider = authTokenProvider;
+   }
+
+   @Override
+   public HttpRequest filter(HttpRequest request) throws HttpException {
+      return request.toBuilder().replaceHeader(AuthHeaders.AUTH_TOKEN, authTokenProvider.get()).build();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticateApiAccessKeyCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticateApiAccessKeyCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticateApiAccessKeyCredentials.java
new file mode 100644
index 0000000..ead326e
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticateApiAccessKeyCredentials.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.openstack.keystone.auth.functions;
+
+import static org.jclouds.openstack.keystone.auth.config.CredentialTypes.API_ACCESS_KEY_CREDENTIALS;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.openstack.keystone.auth.AuthenticationApi;
+import org.jclouds.openstack.keystone.auth.config.CredentialType;
+import org.jclouds.openstack.keystone.auth.domain.ApiAccessKeyCredentials;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+
+@CredentialType(API_ACCESS_KEY_CREDENTIALS)
+@Singleton
+public class AuthenticateApiAccessKeyCredentials extends BaseAuthenticator<ApiAccessKeyCredentials> {
+
+   private final AuthenticationApi auth;
+
+   @Inject
+   AuthenticateApiAccessKeyCredentials(AuthenticationApi auth) {
+      this.auth = auth;
+   }
+
+   @Override
+   public ApiAccessKeyCredentials createCredentials(String identity, String credential) {
+      return ApiAccessKeyCredentials.builder().accessKey(identity).secretKey(credential).build();
+   }
+
+   @Override
+   public AuthInfo authenticate(TenantAndCredentials<ApiAccessKeyCredentials> credentials) {
+      return auth.authenticateAccessKey(credentials);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticatePasswordCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticatePasswordCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticatePasswordCredentials.java
new file mode 100644
index 0000000..dc31b75
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticatePasswordCredentials.java
@@ -0,0 +1,50 @@
+/*
+ * 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.keystone.auth.functions;
+
+import static org.jclouds.openstack.keystone.auth.config.CredentialTypes.PASSWORD_CREDENTIALS;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.openstack.keystone.auth.AuthenticationApi;
+import org.jclouds.openstack.keystone.auth.config.CredentialType;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+import org.jclouds.openstack.keystone.auth.domain.PasswordCredentials;
+
+@CredentialType(PASSWORD_CREDENTIALS)
+@Singleton
+public class AuthenticatePasswordCredentials extends BaseAuthenticator<PasswordCredentials> {
+
+   private final AuthenticationApi auth;
+
+   @Inject
+   AuthenticatePasswordCredentials(AuthenticationApi auth) {
+      this.auth = auth;
+   }
+
+   @Override
+   public PasswordCredentials createCredentials(String identity, String credential) {
+      return PasswordCredentials.builder().username(identity).password(credential).build();
+   }
+
+   @Override
+   public AuthInfo authenticate(TenantAndCredentials<PasswordCredentials> credentials) {
+      return auth.authenticatePassword(credentials);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticateTokenCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticateTokenCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticateTokenCredentials.java
new file mode 100644
index 0000000..70d6381
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/AuthenticateTokenCredentials.java
@@ -0,0 +1,50 @@
+/*
+ * 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.keystone.auth.functions;
+
+import static org.jclouds.openstack.keystone.auth.config.CredentialTypes.TOKEN_CREDENTIALS;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.openstack.keystone.auth.AuthenticationApi;
+import org.jclouds.openstack.keystone.auth.config.CredentialType;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+import org.jclouds.openstack.keystone.auth.domain.TokenCredentials;
+
+@CredentialType(TOKEN_CREDENTIALS)
+@Singleton
+public class AuthenticateTokenCredentials extends BaseAuthenticator<TokenCredentials> {
+
+   private final AuthenticationApi auth;
+
+   @Inject
+   AuthenticateTokenCredentials(AuthenticationApi auth) {
+      this.auth = auth;
+   }
+
+   @Override
+   public TokenCredentials createCredentials(String identity, String credential) {
+      return TokenCredentials.builder().id(credential).build();
+   }
+
+   @Override
+   public AuthInfo authenticate(TenantAndCredentials<TokenCredentials> credentials) {
+      return auth.authenticateToken(credentials);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/BaseAuthenticator.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/BaseAuthenticator.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/BaseAuthenticator.java
new file mode 100644
index 0000000..05b2b94
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/functions/BaseAuthenticator.java
@@ -0,0 +1,88 @@
+/*
+ * 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.keystone.auth.functions;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.REQUIRES_TENANT;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.TENANT_ID;
+import static org.jclouds.openstack.keystone.config.KeystoneProperties.TENANT_NAME;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+
+import org.jclouds.domain.Credentials;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+import org.jclouds.openstack.keystone.auth.domain.TenantAndCredentials;
+
+import com.google.common.base.Function;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+public abstract class BaseAuthenticator<C> implements Function<Credentials, AuthInfo> {
+
+   @Resource
+   protected Logger logger = Logger.NULL;
+
+   @Inject(optional = true)
+   @Named(TENANT_NAME)
+   protected String defaultTenantName;
+
+   @Inject(optional = true)
+   @Named(TENANT_ID)
+   protected String defaultTenantId;
+
+   @Inject(optional = true)
+   @Named(REQUIRES_TENANT)
+   protected boolean requiresTenant;
+
+   @PostConstruct
+   public void checkPropertiesAreCompatible() {
+      checkState(defaultTenantName == null || defaultTenantId == null, "you cannot specify both %s and %s",
+            TENANT_NAME, TENANT_ID);
+   }
+
+   @Override
+   public AuthInfo apply(Credentials input) {
+      String tenantName = defaultTenantName;
+      String usernameOrAccessKey = input.identity;
+      String passwordOrSecretKeyOrToken = input.credential;
+
+      if (defaultTenantName == null && input.identity.indexOf(':') != -1) {
+         tenantName = input.identity.substring(0, input.identity.lastIndexOf(':'));
+         usernameOrAccessKey = input.identity.substring(input.identity.lastIndexOf(':') + 1);
+      }
+
+      if (defaultTenantId == null && tenantName == null && requiresTenant) {
+         throw new IllegalArgumentException(
+               String.format(
+                     "current configuration is set to [%s]. Unless you set [%s] or [%s], you must prefix your identity with 'tenantName:'",
+                     REQUIRES_TENANT, TENANT_NAME, TENANT_ID));
+      }
+      
+      C creds = createCredentials(usernameOrAccessKey, passwordOrSecretKeyOrToken);
+      TenantAndCredentials<C> credsWithTenant = TenantAndCredentials.<C> builder().tenantId(defaultTenantId)
+            .tenantName(tenantName).credentials(creds).build();
+      
+      return authenticate(credsWithTenant);
+   }
+
+   public abstract C createCredentials(String identity, String credential);
+   
+   public abstract AuthInfo authenticate(TenantAndCredentials<C> credentials);
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/handlers/RetryOnRenew.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/handlers/RetryOnRenew.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/handlers/RetryOnRenew.java
new file mode 100644
index 0000000..23ef7a1
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/auth/handlers/RetryOnRenew.java
@@ -0,0 +1,121 @@
+/*
+ * 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.keystone.auth.handlers;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.Constants;
+import org.jclouds.domain.Credentials;
+import org.jclouds.http.HttpCommand;
+import org.jclouds.http.HttpResponse;
+import org.jclouds.http.HttpRetryHandler;
+import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
+import org.jclouds.logging.Logger;
+import org.jclouds.openstack.keystone.auth.AuthHeaders;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.Uninterruptibles;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * This will parse and set an appropriate exception on the command object.
+ */
+@Singleton
+public class RetryOnRenew implements HttpRetryHandler {
+   @Resource
+   protected Logger logger = Logger.NULL;
+
+   @VisibleForTesting
+   @Inject(optional = true)
+   @Named(Constants.PROPERTY_MAX_RETRIES)
+   static int NUM_RETRIES = 5;
+
+   private final LoadingCache<Credentials, AuthInfo> authenticationResponseCache;
+
+   private final BackoffLimitedRetryHandler backoffHandler;
+
+   @Inject
+   RetryOnRenew(LoadingCache<Credentials, AuthInfo> authenticationResponseCache,
+         BackoffLimitedRetryHandler backoffHandler) {
+      this.authenticationResponseCache = authenticationResponseCache;
+      this.backoffHandler = backoffHandler;
+   }
+
+   /*
+    * The reason retries need to be tracked is that it is possible that a token
+    * can be expired at any time. The reason we track by request is that only
+    * some requests might return a 401 (such as temporary URLs). However
+    * consistent failures of the magnitude this code tracks should indicate a
+    * problem.
+    */
+   private static final Cache<HttpCommand, Integer> retryCountMap = CacheBuilder.newBuilder()
+         .expireAfterWrite(5, TimeUnit.MINUTES).build();
+
+   @Override
+   public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
+      boolean retry = false; // default
+      switch (response.getStatusCode()) {
+         case 401:
+            // Do not retry on 401 from authentication request
+            Multimap<String, String> headers = command.getCurrentRequest().getHeaders();
+            if (headers != null && headers.containsKey(AuthHeaders.AUTH_USER)
+                  && headers.containsKey(AuthHeaders.AUTH_KEY) && !headers.containsKey(AuthHeaders.AUTH_TOKEN)) {
+               retry = false;
+            } else {
+               // This is not an authentication request returning 401
+               // Check if we already had seen this request
+               Integer count = retryCountMap.getIfPresent(command);
+
+               if (count == null) {
+                  // First time this non-authentication request failed
+                  logger.debug("invalidating authentication token - first time for %s", command);
+                  retryCountMap.put(command, 1);
+                  authenticationResponseCache.invalidateAll();
+                  retry = true;
+               } else {
+                  // This request has failed before
+                  if (count + 1 >= NUM_RETRIES) {
+                     logger.debug("too many 401s - giving up after: %s for %s", count, command);
+                     retry = false;
+                  } else {
+                     // Retry just in case
+                     logger.debug("invalidating authentication token - retry %s for %s", count, command);
+                     retryCountMap.put(command, count + 1);
+                     // Wait between retries
+                     authenticationResponseCache.invalidateAll();
+                     Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS);
+                     retry = true;
+                  }
+               }
+            }
+            break;
+         case 408:
+            return backoffHandler.shouldRetryRequest(command, response);
+      }
+      return retry;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/ServiceEndpoint.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/ServiceEndpoint.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/ServiceEndpoint.java
new file mode 100644
index 0000000..139751e
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/ServiceEndpoint.java
@@ -0,0 +1,74 @@
+/*
+ * 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.keystone.catalog;
+
+import java.net.URI;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Enums;
+
+/**
+ * Common properties for OpenStack service endpoints.
+ * <p>
+ * This class provides a common view on the service catalog endpoints so it can
+ * be parsed in a generic way for Keystone v2 and v3.
+ */
+@AutoValue
+public abstract class ServiceEndpoint {
+
+   public static enum Interface {
+      PUBLIC, ADMIN, INTERNAL, UNRECOGNIZED;
+
+      public static Interface fromValue(String iface) {
+         return Enums.getIfPresent(Interface.class, iface.toLowerCase()).or(UNRECOGNIZED);
+      }
+   }
+
+   @Nullable public abstract String id();
+   @Nullable public abstract String regionId();
+   public abstract URI url();
+   public abstract Interface iface();
+   public abstract String type();
+   @Nullable public abstract String version();
+   
+   ServiceEndpoint() {
+      
+   }
+   
+   public static Builder builder() {
+      return new AutoValue_ServiceEndpoint.Builder();
+   }
+   
+   @AutoValue.Builder
+   public abstract static class Builder {
+      public abstract Builder id(String id);
+      public abstract Builder regionId(String regionId);
+      public abstract Builder url(URI url);
+      public abstract Builder iface(Interface iface);
+      public abstract Builder type(String type);
+      public abstract Builder version(String version);
+      
+      public Builder iface(String iface) {
+         return iface(Interface.fromValue(iface));
+      }
+      
+      public abstract ServiceEndpoint build();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/InternalUrlModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/InternalUrlModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/InternalUrlModule.java
new file mode 100644
index 0000000..bda2bed
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/InternalUrlModule.java
@@ -0,0 +1,35 @@
+/*
+ * 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.keystone.catalog.config;
+
+import org.jclouds.openstack.keystone.catalog.functions.InternalURL;
+import org.jclouds.openstack.keystone.catalog.functions.ServiceEndpointResolutionStrategy;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Singleton;
+
+/**
+ * Guice module to configure JClouds in order to use the internal urls to
+ * communicate with the services.
+ */
+@Singleton
+public class InternalUrlModule extends AbstractModule {
+   @Override
+   protected void configure() {
+      bind(ServiceEndpointResolutionStrategy.class).to(InternalURL.class);
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/KeystoneAdminURLModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/KeystoneAdminURLModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/KeystoneAdminURLModule.java
new file mode 100644
index 0000000..d670973
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/catalog/config/KeystoneAdminURLModule.java
@@ -0,0 +1,64 @@
+/*
+ * 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.keystone.catalog.config;
+
+import static org.jclouds.util.Suppliers2.getLastValueInMap;
+
+import java.net.URI;
+import java.util.NoSuchElementException;
+
+import javax.inject.Singleton;
+
+import org.jclouds.location.Provider;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
+import org.jclouds.openstack.keystone.catalog.suppliers.RegionIdToAdminURISupplier;
+import org.jclouds.openstack.v2_0.ServiceType;
+import org.jclouds.openstack.v2_0.services.Identity;
+import org.jclouds.rest.annotations.ApiVersion;
+import org.jclouds.util.Suppliers2;
+
+import com.google.common.base.Supplier;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+
+public class KeystoneAdminURLModule extends AbstractModule {
+
+   @Override
+   protected void configure() {
+      install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
+               RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
+   }
+
+   /**
+    * in some cases, there is no {@link ServiceType#IDENTITY} entry in the service catalog. In
+    * other cases, there's no adminURL entry present. Fallback to the provider in this case.
+    */
+   @Provides
+   @Singleton
+   @Identity
+   protected final Supplier<URI> provideIdentityAdminUrl(final RegionIdToAdminURISupplier.Factory factory,
+            @ApiVersion final String version, @Provider final Supplier<URI> providerURI) {
+      Supplier<URI> identityServiceForVersion = getLastValueInMap(factory.createForApiTypeAndVersion(
+               ServiceType.IDENTITY, version));
+      Supplier<URI> whenIdentityServiceIsntListedFallbackToProviderURI = Suppliers2.onThrowable(
+               identityServiceForVersion, NoSuchElementException.class, providerURI);
+      Supplier<URI> whenIdentityServiceHasNoAdminURLFallbackToProviderURI = Suppliers2.or(
+               whenIdentityServiceIsntListedFallbackToProviderURI, providerURI);
+      return whenIdentityServiceHasNoAdminURLFallbackToProviderURI;
+   }
+}


[5/8] jclouds git commit: Initial work towards Keystone V3 authentication

Posted by na...@apache.org.
http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneHttpApiModule.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneHttpApiModule.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneHttpApiModule.java
index fc8aca3..34c2358 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneHttpApiModule.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneHttpApiModule.java
@@ -16,10 +16,7 @@
  */
 package org.jclouds.openstack.keystone.v2_0.config;
 
-import static org.jclouds.util.Suppliers2.getLastValueInMap;
-
 import java.net.URI;
-import java.util.NoSuchElementException;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
@@ -29,30 +26,21 @@ import org.jclouds.http.HttpErrorHandler;
 import org.jclouds.http.annotation.ClientError;
 import org.jclouds.http.annotation.Redirection;
 import org.jclouds.http.annotation.ServerError;
-import org.jclouds.location.Provider;
 import org.jclouds.openstack.keystone.v2_0.KeystoneApi;
 import org.jclouds.openstack.keystone.v2_0.handlers.KeystoneErrorHandler;
-import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
-import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier;
-import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.domain.Extension;
 import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationMatchesExtensionSet;
-import org.jclouds.openstack.v2_0.services.Identity;
 import org.jclouds.rest.ConfiguresHttpApi;
-import org.jclouds.rest.annotations.ApiVersion;
 import org.jclouds.rest.config.HttpApiModule;
 import org.jclouds.rest.functions.ImplicitOptionalConverter;
-import org.jclouds.util.Suppliers2;
 
 import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
-import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
 import com.google.inject.Provides;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
 import com.google.inject.multibindings.MapBinder;
 
 /**
@@ -64,33 +52,6 @@ public class KeystoneHttpApiModule extends HttpApiModule<KeystoneApi> {
    public KeystoneHttpApiModule() {
    }
 
-   public static class KeystoneAdminURLModule extends AbstractModule {
-
-      @Override
-      protected void configure() {
-         install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
-                  RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
-      }
-
-      /**
-       * in some cases, there is no {@link ServiceType#IDENTITY} entry in the service catalog. In
-       * other cases, there's no adminURL entry present. Fallback to the provider in this case.
-       */
-      @Provides
-      @Singleton
-      @Identity
-      protected final Supplier<URI> provideStorageUrl(final RegionIdToAdminURISupplier.Factory factory,
-               @ApiVersion final String version, @Provider final Supplier<URI> providerURI) {
-         Supplier<URI> identityServiceForVersion = getLastValueInMap(factory.createForApiTypeAndVersion(
-                  ServiceType.IDENTITY, version));
-         Supplier<URI> whenIdentityServiceIsntListedFallbackToProviderURI = Suppliers2.onThrowable(
-                  identityServiceForVersion, NoSuchElementException.class, providerURI);
-         Supplier<URI> whenIdentityServiceHasNoAdminURLFallbackToProviderURI = Suppliers2.or(
-                  whenIdentityServiceIsntListedFallbackToProviderURI, providerURI);
-         return whenIdentityServiceHasNoAdminURLFallbackToProviderURI;
-      }
-   }
-
    // Allow providers to cleanly contribute their own aliases
    public static MapBinder<URI, URI> namespaceAliasBinder(Binder binder) {
       return MapBinder.newMapBinder(binder, URI.class, URI.class, NamespaceAliases.class).permitDuplicates();

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneProperties.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneProperties.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneProperties.java
deleted file mode 100644
index dcb83cf..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneProperties.java
+++ /dev/null
@@ -1,75 +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.keystone.v2_0.config;
-
-/**
- * Configuration properties and constants used in Keystone connections.
- */
-public final class KeystoneProperties {
-
-   /**
-    * Type of credentials used to log into the auth service.
-    *
-    * <h3>valid values</h3>
-    * <ul>
-    * <li>apiAccessKeyCredentials</li>
-    * <li>passwordCredentials</li>
-    * </ul>
-    *
-    * @see CredentialTypes
-    * @see <a href=
-    *      "http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_Service_API_Api_Operations.html"
-    *      />
-    */
-   public static final String CREDENTIAL_TYPE = "jclouds.keystone.credential-type";
-
-   /**
-    * set this property to specify the tenant id of the authenticated user.
-    * Cannot be used simultaneously with {@link #TENANT_NAME}
-    *
-    * @see <a href="http://wiki.openstack.org/CLIAuth">openstack docs</a>
-    */
-   public static final String TENANT_ID = "jclouds.keystone.tenant-id";
-
-   /**
-    * set this property to specify the tenant name of the authenticated user.
-    * Cannot be used simultaneously with {@link #TENANT_ID}
-    *
-    * @see <a href="http://wiki.openstack.org/CLIAuth">openstack docs</a>
-    */
-   public static final String TENANT_NAME = "jclouds.keystone.tenant-name";
-
-   /**
-    * set this property to {@code true} to designate that the service requires
-    * explicit specification of either {@link #TENANT_NAME} or
-    * {@link #TENANT_ID}
-    *
-    * @see <a href="http://wiki.openstack.org/CLIAuth">openstack docs</a>
-    */
-   public static final String REQUIRES_TENANT = "jclouds.keystone.requires-tenant";
-
-   /**
-    * type of the keystone service. ex. {@code compute}
-    *
-    * @see ServiceType
-    */
-   public static final String SERVICE_TYPE = "jclouds.keystone.service-type";
-
-   private KeystoneProperties() {
-      throw new AssertionError("intentionally unimplemented");
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Access.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Access.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Access.java
index eb63a31..58dac28 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Access.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Access.java
@@ -22,6 +22,7 @@ import java.beans.ConstructorProperties;
 import java.util.Set;
 
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.domain.AuthInfo;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Objects;
@@ -36,7 +37,7 @@ import com.google.common.collect.ImmutableSet;
  *      "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Identity-Service-Concepts-e1362.html"
  *      />
  */
-public class Access extends ForwardingSet<Service> implements Comparable<Access> {
+public class Access extends ForwardingSet<Service> implements Comparable<Access>, AuthInfo {
 
    public static Builder<?> builder() {
       return new ConcreteBuilder();
@@ -166,4 +167,9 @@ public class Access extends ForwardingSet<Service> implements Comparable<Access>
       return serviceCatalog;
    }
 
+   @Override
+   public String getAuthToken() {
+      return token.getId();
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/ApiAccessKeyCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/ApiAccessKeyCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/ApiAccessKeyCredentials.java
deleted file mode 100644
index b189a2f..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/ApiAccessKeyCredentials.java
+++ /dev/null
@@ -1,140 +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.keystone.v2_0.domain;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.beans.ConstructorProperties;
-
-import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
-import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Api AccessKey Credentials
- *
- * @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_Service_API_Api_Operations.html#d662e583"
-/>
- */
-@CredentialType(CredentialTypes.API_ACCESS_KEY_CREDENTIALS)
-public class ApiAccessKeyCredentials {
-
-   public static Builder<?> builder() {
-      return new ConcreteBuilder();
-   }
-
-   public Builder<?> toBuilder() {
-      return new ConcreteBuilder().fromApiAccessKeyCredentials(this);
-   }
-
-   public static ApiAccessKeyCredentials createWithAccessKeyAndSecretKey(String accessKey, String secretKey) {
-      return new ApiAccessKeyCredentials(accessKey, secretKey);
-   }
-
-   public abstract static class Builder<T extends Builder<T>>  {
-      protected abstract T self();
-
-      protected String accessKey;
-      protected String secretKey;
-
-      /**
-       * @see ApiAccessKeyCredentials#getAccessKey()
-       */
-      public T accessKey(String accessKey) {
-         this.accessKey = accessKey;
-         return self();
-      }
-
-      /**
-       * @see ApiAccessKeyCredentials#getSecretKey()
-       */
-      public T secretKey(String secretKey) {
-         this.secretKey = secretKey;
-         return self();
-      }
-
-      public ApiAccessKeyCredentials build() {
-         return new ApiAccessKeyCredentials(accessKey, secretKey);
-      }
-
-      public T fromApiAccessKeyCredentials(ApiAccessKeyCredentials in) {
-         return this
-               .accessKey(in.getAccessKey())
-               .secretKey(in.getSecretKey());
-      }
-   }
-
-   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
-      @Override
-      protected ConcreteBuilder self() {
-         return this;
-      }
-   }
-
-   private final String accessKey;
-   private final String secretKey;
-
-   @ConstructorProperties({
-         "accessKey", "secretKey"
-   })
-   protected ApiAccessKeyCredentials(String accessKey, String secretKey) {
-      this.accessKey = checkNotNull(accessKey, "accessKey");
-      this.secretKey = checkNotNull(secretKey, "secretKey");
-   }
-
-   /**
-    * @return the accessKey
-    */
-   public String getAccessKey() {
-      return this.accessKey;
-   }
-
-   /**
-    * @return the secretKey
-    */
-   public String getSecretKey() {
-      return this.secretKey;
-   }
-
-   @Override
-   public int hashCode() {
-      return Objects.hashCode(accessKey, secretKey);
-   }
-
-   @Override
-   public boolean equals(Object obj) {
-      if (this == obj) return true;
-      if (obj == null || getClass() != obj.getClass()) return false;
-      ApiAccessKeyCredentials that = ApiAccessKeyCredentials.class.cast(obj);
-      return Objects.equal(this.accessKey, that.accessKey)
-            && Objects.equal(this.secretKey, that.secretKey);
-   }
-
-   protected ToStringHelper string() {
-      return MoreObjects.toStringHelper(this)
-            .add("accessKey", accessKey).add("secretKey", secretKey);
-   }
-
-   @Override
-   public String toString() {
-      return string().toString();
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Endpoint.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Endpoint.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Endpoint.java
index f5424bd..0080b2e 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Endpoint.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/Endpoint.java
@@ -22,8 +22,8 @@ import java.net.URI;
 import org.jclouds.javax.annotation.Nullable;
 
 import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
 import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Objects;
 
 /**
  * An network-accessible address, usually described by URL, where a service may

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/PasswordCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/PasswordCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/PasswordCredentials.java
deleted file mode 100644
index 68b5f99..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/domain/PasswordCredentials.java
+++ /dev/null
@@ -1,140 +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.keystone.v2_0.domain;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.beans.ConstructorProperties;
-
-import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Objects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Password Credentials
- *
- * @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_Service_API_Api_Operations.html#d662e583"
-/>
- */
-@CredentialType("passwordCredentials")
-public class PasswordCredentials {
-
-   public static Builder<?> builder() {
-      return new ConcreteBuilder();
-   }
-
-   public Builder<?> toBuilder() {
-      return new ConcreteBuilder().fromPasswordCredentials(this);
-   }
-
-   public static PasswordCredentials createWithUsernameAndPassword(String username, String password) {
-      return new PasswordCredentials(username, password);
-   }
-
-   public abstract static class Builder<T extends Builder<T>>  {
-      protected abstract T self();
-
-      protected String username;
-      protected String password;
-
-      /**
-       * @see PasswordCredentials#getUsername()
-       */
-      public T username(String username) {
-         this.username = username;
-         return self();
-      }
-
-      /**
-       * @see PasswordCredentials#getPassword()
-       */
-      public T password(String password) {
-         this.password = password;
-         return self();
-      }
-
-      public PasswordCredentials build() {
-         return new PasswordCredentials(username, password);
-      }
-
-      public T fromPasswordCredentials(PasswordCredentials in) {
-         return this
-               .username(in.getUsername())
-               .password(in.getPassword());
-      }
-   }
-
-   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
-      @Override
-      protected ConcreteBuilder self() {
-         return this;
-      }
-   }
-
-   private final String username;
-   private final String password;
-
-   @ConstructorProperties({
-         "username", "password"
-   })
-   protected PasswordCredentials(String username, String password) {
-      this.username = checkNotNull(username, "username");
-      this.password = checkNotNull(password, "password");
-   }
-
-   /**
-    * @return the username
-    */
-   public String getUsername() {
-      return this.username;
-   }
-
-   /**
-    * @return the password
-    */
-   public String getPassword() {
-      return this.password;
-   }
-
-   @Override
-   public int hashCode() {
-      return Objects.hashCode(username, password);
-   }
-
-   @Override
-   public boolean equals(Object obj) {
-      if (this == obj) return true;
-      if (obj == null || getClass() != obj.getClass()) return false;
-      PasswordCredentials that = PasswordCredentials.class.cast(obj);
-      return Objects.equal(this.username, that.username)
-            && Objects.equal(this.password, that.password);
-   }
-
-   protected ToStringHelper string() {
-      return MoreObjects.toStringHelper(this)
-            .add("username", username)
-            .add("password", password == null ? null : "*****");
-   }
-
-   @Override
-   public String toString() {
-      return string().toString();
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/RoleAdminApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/RoleAdminApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/RoleAdminApi.java
index 2d11b16..f5ced86 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/RoleAdminApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/RoleAdminApi.java
@@ -30,8 +30,8 @@ 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.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.domain.Role;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.ServiceType;
 import org.jclouds.openstack.v2_0.services.Extension;
 import org.jclouds.rest.annotations.Fallback;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/ServiceAdminApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/ServiceAdminApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/ServiceAdminApi.java
index 8c9b8cf..2bba9fa 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/ServiceAdminApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/ServiceAdminApi.java
@@ -30,9 +30,9 @@ import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
 import org.jclouds.openstack.keystone.v2_0.domain.Service;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseServices;
 import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseServices.ToPagedIterable;
 import org.jclouds.openstack.v2_0.ServiceType;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/TenantAdminApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/TenantAdminApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/TenantAdminApi.java
index 93489b3..f3dec87 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/TenantAdminApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/TenantAdminApi.java
@@ -28,8 +28,8 @@ import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.options.CreateTenantOptions;
 import org.jclouds.openstack.keystone.v2_0.options.UpdateTenantOptions;
 import org.jclouds.openstack.v2_0.ServiceType;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/UserAdminApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/UserAdminApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/UserAdminApi.java
index 952b4a1..7102fca 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/UserAdminApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/extensions/UserAdminApi.java
@@ -27,8 +27,8 @@ import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.domain.User;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.options.CreateUserOptions;
 import org.jclouds.openstack.keystone.v2_0.options.UpdateUserOptions;
 import org.jclouds.openstack.v2_0.ServiceType;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/ServiceApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/ServiceApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/ServiceApi.java
index dbf982d..0836318 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/ServiceApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/ServiceApi.java
@@ -25,8 +25,8 @@ import javax.ws.rs.Path;
 import javax.ws.rs.core.MediaType;
 
 import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;
 import org.jclouds.rest.annotations.SelectJson;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TenantApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TenantApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TenantApi.java
index 85828bf..1136a2f 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TenantApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TenantApi.java
@@ -27,9 +27,9 @@ import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
 import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseTenants;
 import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseTenants.ToPagedIterable;
 import org.jclouds.openstack.v2_0.domain.PaginatedCollection;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TokenApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TokenApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TokenApi.java
index f61dc8b..a6d3961 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TokenApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/TokenApi.java
@@ -30,10 +30,10 @@ import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
 import org.jclouds.Fallbacks.FalseOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
 import org.jclouds.openstack.keystone.v2_0.domain.Token;
 import org.jclouds.openstack.keystone.v2_0.domain.User;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.v2_0.services.Identity;
 import org.jclouds.rest.annotations.Fallback;
 import org.jclouds.rest.annotations.RequestFilters;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/UserApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/UserApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/UserApi.java
index f7dd75e..11d1ac0 100644
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/UserApi.java
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/features/UserApi.java
@@ -31,10 +31,10 @@ import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404;
 import org.jclouds.Fallbacks.NullOnNotFoundOr404;
 import org.jclouds.collect.PagedIterable;
 import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.openstack.keystone.auth.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;
 import org.jclouds.openstack.keystone.v2_0.domain.Role;
 import org.jclouds.openstack.keystone.v2_0.domain.User;
-import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
 import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseUsers;
 import org.jclouds.openstack.keystone.v2_0.functions.internal.ParseUsers.ToPagedIterable;
 import org.jclouds.openstack.v2_0.domain.PaginatedCollection;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/filters/AuthenticateRequest.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/filters/AuthenticateRequest.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/filters/AuthenticateRequest.java
deleted file mode 100644
index b46899c..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/filters/AuthenticateRequest.java
+++ /dev/null
@@ -1,48 +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.keystone.v2_0.filters;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.jclouds.http.HttpException;
-import org.jclouds.http.HttpRequest;
-import org.jclouds.http.HttpRequestFilter;
-import org.jclouds.openstack.keystone.v2_0.config.Authentication;
-import org.jclouds.openstack.v2_0.reference.AuthHeaders;
-
-import com.google.common.base.Supplier;
-
-/**
- * Signs the Keystone-based request. This will update the Authentication Token before 24 hours is up.
- */
-@Singleton
-public class AuthenticateRequest implements HttpRequestFilter {
-
-   private final Supplier<String> authTokenProvider;
-
-   @Inject
-   public AuthenticateRequest(@Authentication Supplier<String> authTokenProvider) {
-      this.authTokenProvider = authTokenProvider;
-   }
-
-   @Override
-   public HttpRequest filter(HttpRequest request) throws HttpException {
-      return request.toBuilder().replaceHeader(AuthHeaders.AUTH_TOKEN, authTokenProvider.get()).build();
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AdminURL.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AdminURL.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AdminURL.java
deleted file mode 100644
index 2669965..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AdminURL.java
+++ /dev/null
@@ -1,38 +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.keystone.v2_0.functions;
-
-import java.net.URI;
-
-import javax.inject.Singleton;
-
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-
-@Singleton
-public class AdminURL implements EndpointToSupplierAdminURI {
-   @Override
-   public Supplier<URI> apply(Endpoint input) {
-      return Suppliers.ofInstance(input.getAdminURL());
-   }
-
-   public String toString() {
-      return "supplyAdminURL()";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticateApiAccessKeyCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticateApiAccessKeyCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticateApiAccessKeyCredentials.java
deleted file mode 100644
index 7a42f33..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticateApiAccessKeyCredentials.java
+++ /dev/null
@@ -1,60 +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.keystone.v2_0.functions;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
-import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
-import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials;
-import org.jclouds.openstack.keystone.v2_0.functions.internal.BaseAuthenticator;
-
-import com.google.common.base.Optional;
-
-@CredentialType(CredentialTypes.API_ACCESS_KEY_CREDENTIALS)
-@Singleton
-public class AuthenticateApiAccessKeyCredentials extends BaseAuthenticator<ApiAccessKeyCredentials> {
-   protected final AuthenticationApi api;
-
-   @Inject
-   public AuthenticateApiAccessKeyCredentials(AuthenticationApi api) {
-      this.api = api;
-   }
-
-   @Override
-   protected Access authenticateWithTenantName(Optional<String> tenantName, ApiAccessKeyCredentials apiAccessKeyCredentials) {
-      return api.authenticateWithTenantNameAndCredentials(tenantName.orNull(), apiAccessKeyCredentials);
-   }
-
-   @Override
-   protected Access authenticateWithTenantId(Optional<String> tenantId, ApiAccessKeyCredentials apiAccessKeyCredentials) {
-      return api.authenticateWithTenantIdAndCredentials(tenantId.orNull(), apiAccessKeyCredentials);
-   }
-
-   @Override
-   public ApiAccessKeyCredentials createCredentials(String identity, String credential) {
-      return ApiAccessKeyCredentials.createWithAccessKeyAndSecretKey(identity, credential);
-   }
-
-   @Override
-   public String toString() {
-      return "authenticateApiAccessKeyCredentials()";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticatePasswordCredentials.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticatePasswordCredentials.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticatePasswordCredentials.java
deleted file mode 100644
index 15d1237..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticatePasswordCredentials.java
+++ /dev/null
@@ -1,60 +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.keystone.v2_0.functions;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.jclouds.openstack.keystone.v2_0.AuthenticationApi;
-import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
-import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
-import org.jclouds.openstack.keystone.v2_0.functions.internal.BaseAuthenticator;
-
-import com.google.common.base.Optional;
-
-@CredentialType(CredentialTypes.PASSWORD_CREDENTIALS)
-@Singleton
-public class AuthenticatePasswordCredentials extends BaseAuthenticator<PasswordCredentials> {
-   protected final AuthenticationApi api;
-
-   @Inject
-   public AuthenticatePasswordCredentials(AuthenticationApi api) {
-      this.api = api;
-   }
-
-   @Override
-   protected Access authenticateWithTenantName(Optional<String> tenantName, PasswordCredentials apiAccessKeyCredentials) {
-      return api.authenticateWithTenantNameAndCredentials(tenantName.orNull(), apiAccessKeyCredentials);
-   }
-
-   @Override
-   protected Access authenticateWithTenantId(Optional<String> tenantId, PasswordCredentials apiAccessKeyCredentials) {
-      return api.authenticateWithTenantIdAndCredentials(tenantId.orNull(), apiAccessKeyCredentials);
-   }
-
-   @Override
-   public PasswordCredentials createCredentials(String identity, String credential) {
-      return PasswordCredentials.createWithUsernameAndPassword(identity, credential);
-   }
-
-   @Override
-   public String toString() {
-      return "authenticatePasswordCredentials()";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToRegion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToRegion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToRegion.java
deleted file mode 100644
index d3ec6d6..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToRegion.java
+++ /dev/null
@@ -1,27 +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.keystone.v2_0.functions;
-
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-
-import com.google.common.base.Function;
-import com.google.inject.ImplementedBy;
-
-@ImplementedBy(ReturnRegionOrProvider.class)
-public interface EndpointToRegion extends Function<Endpoint, String> {
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToSupplierAdminURI.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToSupplierAdminURI.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToSupplierAdminURI.java
deleted file mode 100644
index 6bf6e11..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToSupplierAdminURI.java
+++ /dev/null
@@ -1,23 +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.keystone.v2_0.functions;
-
-import com.google.inject.ImplementedBy;
-
-@ImplementedBy(AdminURL.class)
-public interface EndpointToSupplierAdminURI extends EndpointToSupplierURI {  
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToSupplierURI.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToSupplierURI.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToSupplierURI.java
deleted file mode 100644
index 8b424f7..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/EndpointToSupplierURI.java
+++ /dev/null
@@ -1,29 +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.keystone.v2_0.functions;
-
-import java.net.URI;
-
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-import com.google.inject.ImplementedBy;
-
-@ImplementedBy(PublicURLOrInternalIfNull.class)
-public interface EndpointToSupplierURI extends Function<Endpoint, Supplier<URI>> {  
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/InternalURL.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/InternalURL.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/InternalURL.java
deleted file mode 100644
index fbd23d2..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/InternalURL.java
+++ /dev/null
@@ -1,43 +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.keystone.v2_0.functions;
-
-import java.net.URI;
-
-import javax.inject.Singleton;
-
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-
-/**
- * Select internal URL endpoints services
- * 
- */
-@Singleton
-public class InternalURL implements EndpointToSupplierURI {
-   @Override
-   public Supplier<URI> apply(Endpoint input) {
-      return Suppliers.ofInstance(input.getInternalURL());
-   }
-
-   @Override
-   public String toString() {
-      return "supplyInternalURL()";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/PublicURLOrInternalIfNull.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/PublicURLOrInternalIfNull.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/PublicURLOrInternalIfNull.java
deleted file mode 100644
index 01d81bd..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/PublicURLOrInternalIfNull.java
+++ /dev/null
@@ -1,39 +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.keystone.v2_0.functions;
-
-import java.net.URI;
-
-import javax.inject.Singleton;
-
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-
-@Singleton
-public class PublicURLOrInternalIfNull implements EndpointToSupplierURI {
-   // TODO: check accessibility and prioritize private first
-   @Override
-   public Supplier<URI> apply(Endpoint input) {
-      return Suppliers.ofInstance(input.getPublicURL() != null ? input.getPublicURL() : input.getInternalURL());
-   }
-
-   public String toString() {
-      return "supplyPublicURL()";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/RegionToAdminEndpointURI.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/RegionToAdminEndpointURI.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/RegionToAdminEndpointURI.java
deleted file mode 100644
index c6c1a34..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/RegionToAdminEndpointURI.java
+++ /dev/null
@@ -1,49 +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.keystone.v2_0.functions;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.net.URI;
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier;
-
-import com.google.common.base.Function;
-import com.google.common.base.Supplier;
-
-public final class RegionToAdminEndpointURI implements Function<Object, URI> {
-
-   private final RegionIdToAdminURISupplier regionToAdminEndpoints;
-
-   @Inject
-   RegionToAdminEndpointURI(RegionIdToAdminURISupplier regionToAdminEndpoints) {
-      this.regionToAdminEndpoints = regionToAdminEndpoints;
-   }
-
-   @Override
-   public URI apply(Object from) {
-      Map<String, Supplier<URI>> regionToAdminEndpoint = regionToAdminEndpoints.get();
-      checkState(!regionToAdminEndpoint.isEmpty(), "no region name to admin endpoint mappings in keystone!");
-      checkArgument(regionToAdminEndpoint.containsKey(from),
-            "requested location %s, which is not in the keystone admin endpoints: %s", from, regionToAdminEndpoint);
-      return regionToAdminEndpoint.get(from).get();
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/ReturnRegionOrProvider.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/ReturnRegionOrProvider.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/ReturnRegionOrProvider.java
deleted file mode 100644
index 2dfc32e..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/ReturnRegionOrProvider.java
+++ /dev/null
@@ -1,40 +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.keystone.v2_0.functions;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.jclouds.location.Provider;
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-
-@Singleton
-public class ReturnRegionOrProvider implements EndpointToRegion {
-   private String provider;
-
-   @Inject
-   ReturnRegionOrProvider(@Provider String provider) {
-      this.provider = checkNotNull(provider, "provider");
-   }
-
-   @Override
-   public String apply(Endpoint input) {
-      return input.getRegion() != null ? input.getRegion() : provider;
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/internal/BaseAuthenticator.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/internal/BaseAuthenticator.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/internal/BaseAuthenticator.java
deleted file mode 100644
index 3e4216a..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/internal/BaseAuthenticator.java
+++ /dev/null
@@ -1,97 +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.keystone.v2_0.functions.internal;
-
-import static com.google.common.base.Preconditions.checkState;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.REQUIRES_TENANT;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.TENANT_ID;
-import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.TENANT_NAME;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.Resource;
-
-import org.jclouds.domain.Credentials;
-import org.jclouds.logging.Logger;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.inject.Inject;
-import com.google.inject.name.Named;
-
-public abstract class BaseAuthenticator<C> implements Function<Credentials, Access> {
-
-   @Resource
-   protected Logger logger = Logger.NULL;
-
-   @Inject(optional = true)
-   @Named(TENANT_NAME)
-   protected String defaultTenantName;
-
-   @Inject(optional = true)
-   @Named(TENANT_ID)
-   protected String defaultTenantId;
-
-   @Inject(optional = true)
-   @Named(REQUIRES_TENANT)
-   protected boolean requiresTenant;
-
-   @PostConstruct
-   public void checkPropertiesAreCompatible() {
-      checkState(defaultTenantName == null || defaultTenantId == null, "you cannot specify both %s and %s",
-            TENANT_NAME, TENANT_ID);
-   }
-
-   @Override
-   public Access apply(Credentials input) {
-      Optional<String> tenantName = Optional.fromNullable(defaultTenantName);
-      Optional<String> tenantId = Optional.fromNullable(defaultTenantId);
-
-      String usernameOrAccessKey = input.identity;
-
-      if (!tenantName.isPresent() && input.identity.indexOf(':') != -1) {
-         tenantName = Optional.of(input.identity.substring(0, input.identity.lastIndexOf(':')));
-         usernameOrAccessKey = input.identity.substring(input.identity.lastIndexOf(':') + 1);
-      }
-
-      String passwordOrSecretKey = input.credential;
-
-      C creds = createCredentials(usernameOrAccessKey, passwordOrSecretKey);
-
-      Access access;
-      if (tenantId.isPresent()) {
-         access = authenticateWithTenantId(tenantId, creds);
-      } else if (tenantName.isPresent()) {
-         access = authenticateWithTenantName(tenantName, creds);
-      } else if (!requiresTenant) {
-         access = authenticateWithTenantName(tenantName, creds);
-      } else {
-         throw new IllegalArgumentException(
-               String.format(
-                     "current configuration is set to [%s]. Unless you set [%s] or [%s], you must prefix your identity with 'tenantName:'",
-                     REQUIRES_TENANT, TENANT_NAME, TENANT_ID));
-      }
-      return access;
-   }
-
-   public abstract C createCredentials(String identity, String credential);
-
-   protected abstract Access authenticateWithTenantId(Optional<String> tenantId, C apiAccessKeyCredentials);
-
-   protected abstract Access authenticateWithTenantName(Optional<String> tenantId, C apiAccessKeyCredentials);
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/handlers/RetryOnRenew.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/handlers/RetryOnRenew.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/handlers/RetryOnRenew.java
deleted file mode 100644
index 5cedc80..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/handlers/RetryOnRenew.java
+++ /dev/null
@@ -1,121 +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.keystone.v2_0.handlers;
-
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Resource;
-import javax.inject.Named;
-
-import org.jclouds.Constants;
-import org.jclouds.domain.Credentials;
-import org.jclouds.http.HttpCommand;
-import org.jclouds.http.HttpResponse;
-import org.jclouds.http.HttpRetryHandler;
-import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
-import org.jclouds.logging.Logger;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.v2_0.reference.AuthHeaders;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.Multimap;
-import com.google.common.util.concurrent.Uninterruptibles;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-
-/**
- * This will parse and set an appropriate exception on the command object.
- */
-@Singleton
-public class RetryOnRenew implements HttpRetryHandler {
-   @Resource
-   protected Logger logger = Logger.NULL;
-
-   @VisibleForTesting
-   @Inject(optional = true)
-   @Named(Constants.PROPERTY_MAX_RETRIES)
-   static int NUM_RETRIES = 5;
-
-   private final LoadingCache<Credentials, Access> authenticationResponseCache;
-
-   private final BackoffLimitedRetryHandler backoffHandler;
-
-   @Inject
-   protected RetryOnRenew(LoadingCache<Credentials, Access> authenticationResponseCache,
-         BackoffLimitedRetryHandler backoffHandler) {
-      this.authenticationResponseCache = authenticationResponseCache;
-      this.backoffHandler = backoffHandler;
-   }
-
-   /*
-    * The reason retries need to be tracked is that it is possible that a token
-    * can be expired at any time. The reason we track by request is that only
-    * some requests might return a 401 (such as temporary URLs). However
-    * consistent failures of the magnitude this code tracks should indicate a
-    * problem.
-    */
-   private static final Cache<HttpCommand, Integer> retryCountMap = CacheBuilder.newBuilder()
-         .expireAfterWrite(5, TimeUnit.MINUTES).build();
-
-   @Override
-   public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
-      boolean retry = false; // default
-      switch (response.getStatusCode()) {
-         case 401:
-            // Do not retry on 401 from authentication request
-            Multimap<String, String> headers = command.getCurrentRequest().getHeaders();
-            if (headers != null && headers.containsKey(AuthHeaders.AUTH_USER)
-                  && headers.containsKey(AuthHeaders.AUTH_KEY) && !headers.containsKey(AuthHeaders.AUTH_TOKEN)) {
-               retry = false;
-            } else {
-               // This is not an authentication request returning 401
-               // Check if we already had seen this request
-               Integer count = retryCountMap.getIfPresent(command);
-
-               if (count == null) {
-                  // First time this non-authentication request failed
-                  logger.debug("invalidating authentication token - first time for %s", command);
-                  retryCountMap.put(command, 1);
-                  authenticationResponseCache.invalidateAll();
-                  retry = true;
-               } else {
-                  // This request has failed before
-                  if (count + 1 >= NUM_RETRIES) {
-                     logger.debug("too many 401s - giving up after: %s for %s", count, command);
-                     retry = false;
-                  } else {
-                     // Retry just in case
-                     logger.debug("invalidating authentication token - retry %s for %s", count, command);
-                     retryCountMap.put(command, count + 1);
-                     // Wait between retries
-                     authenticationResponseCache.invalidateAll();
-                     Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS);
-                     retry = true;
-                  }
-               }
-            }
-            break;
-         case 408:
-            return backoffHandler.shouldRetryRequest(command, response);
-      }
-      return retry;
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java
deleted file mode 100644
index 063f4a6..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersion.java
+++ /dev/null
@@ -1,208 +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.keystone.v2_0.suppliers;
-
-import static com.google.common.collect.Iterables.any;
-import static com.google.common.collect.Iterables.concat;
-import static com.google.common.collect.Iterables.isEmpty;
-import static com.google.common.collect.Iterables.tryFind;
-import static com.google.common.collect.Multimaps.index;
-
-
-import java.net.URI;
-import java.util.Collection;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.annotation.Resource;
-
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.logging.Logger;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
-import org.jclouds.openstack.keystone.v2_0.domain.Service;
-import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierURI;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-
-public class LocationIdToURIFromAccessForTypeAndVersion implements Supplier<Map<String, Supplier<URI>>> {
-
-   public interface Factory {
-      /**
-       *
-       * @param apiType
-       *           type of the api, according to the provider. ex.
-       *           {@code compute} {@code object-store}
-       * @param apiVersion
-       *           version of the api, or null if not available
-       * @return locations mapped to default uri
-       * @throws NoSuchElementException
-       *            if the {@code apiType} is not present in the catalog
-       */
-      LocationIdToURIFromAccessForTypeAndVersion createForApiTypeAndVersion(@Assisted("apiType") String apiType,
-            @Nullable @Assisted("apiVersion") String apiVersion) throws NoSuchElementException;
-   }
-
-   @Resource
-   protected Logger logger = Logger.NULL;
-
-   protected final Supplier<Access> access;
-   protected final EndpointToSupplierURI endpointToSupplierURI;
-   protected final Function<Endpoint, String> endpointToLocationId;
-   protected final String apiType;
-   protected final String apiVersion;
-
-   @Inject
-   public LocationIdToURIFromAccessForTypeAndVersion(Supplier<Access> access,
-         EndpointToSupplierURI endpointToSupplierURI, Function<Endpoint, String> endpointToLocationId,
-         @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
-      this.access = access;
-      this.endpointToSupplierURI = endpointToSupplierURI;
-      this.endpointToLocationId = endpointToLocationId;
-      this.apiType = apiType;
-      this.apiVersion = apiVersion;
-   }
-
-   @Override
-   public Map<String, Supplier<URI>> get() {
-      FluentIterable<Service> services = FluentIterable.from(access.get()).filter(apiTypeEquals);
-      if (services.isEmpty())
-         throw new NoSuchElementException(String.format("apiType %s not found in catalog %s", apiType, services));
-
-      Iterable<Endpoint> endpoints = concat(services);
-
-      if (isEmpty(endpoints))
-         throw new NoSuchElementException(
-               String.format("no endpoints for apiType %s in services %s", apiType, services));
-
-      boolean checkVersionId = any(endpoints, versionAware);
-
-      Multimap<String, Endpoint> locationToEndpoints = index(endpoints, endpointToLocationId);
-      Map<String, Endpoint> locationToEndpoint;
-      if (checkVersionId && apiVersion != null) {
-         locationToEndpoint = refineToVersionSpecificEndpoint(locationToEndpoints);
-         if (locationToEndpoint.size() == 0)
-            throw new NoSuchElementException(String.format(
-                  "no endpoints for apiType %s are of version %s, or version agnostic: %s", apiType, apiVersion,
-                  locationToEndpoints));
-      } else {
-         locationToEndpoint = firstEndpointInLocation(locationToEndpoints);
-      }
-
-      logger.debug("endpoints for apiType %s and version %s: %s", apiType, apiVersion, locationToEndpoints);
-      return Maps.transformValues(locationToEndpoint, endpointToSupplierURI);
-   }
-
-   @VisibleForTesting
-   Map<String, Endpoint> firstEndpointInLocation(Multimap<String, Endpoint> locationToEndpoints) {
-      Builder<String, Endpoint> locationToEndpointBuilder = ImmutableMap.<String, Endpoint> builder();
-      for (Map.Entry<String, Collection<Endpoint>> entry : locationToEndpoints.asMap().entrySet()) {
-         String locationId = entry.getKey();
-         Collection<Endpoint> endpoints = entry.getValue();
-         switch (endpoints.size()) {
-         case 0:
-            logNoEndpointsInLocation(locationId);
-            break;
-         default:
-            locationToEndpointBuilder.put(locationId, Iterables.get(endpoints, 0));
-         }
-      }
-      return locationToEndpointBuilder.build();
-   }
-
-   @VisibleForTesting
-   Map<String, Endpoint> refineToVersionSpecificEndpoint(Multimap<String, Endpoint> locationToEndpoints) {
-      Builder<String, Endpoint> locationToEndpointBuilder = ImmutableMap.<String, Endpoint> builder();
-      for (Map.Entry<String, Collection<Endpoint>> entry : locationToEndpoints.asMap().entrySet()) {
-         String locationId = entry.getKey();
-         Collection<Endpoint> endpoints = entry.getValue();
-         switch (endpoints.size()) {
-         case 0:
-            logNoEndpointsInLocation(locationId);
-            break;
-         default:
-            putIfPresent(locationId, strictMatchEndpointVersion(endpoints, locationId), locationToEndpointBuilder);
-         }
-
-      }
-      return locationToEndpointBuilder.build();
-   }
-
-   /**
-    * Prioritizes endpoint.versionId over endpoint.id when matching
-    */
-   private Optional<Endpoint> strictMatchEndpointVersion(Iterable<Endpoint> endpoints, String locationId) {
-      Optional<Endpoint> endpointOfVersion = tryFind(endpoints, apiVersionEqualsVersionId);
-      if (!endpointOfVersion.isPresent())
-         logger.debug("no endpoints of apiType %s matched expected version %s in location %s: %s", apiType, apiVersion,
-               locationId, endpoints);
-      return endpointOfVersion;
-   }
-
-   private void logNoEndpointsInLocation(String locationId) {
-      logger.debug("no endpoints found for apiType %s in location %s", apiType, locationId);
-   }
-
-   private final Predicate<Endpoint> apiVersionEqualsVersionId = new Predicate<Endpoint>() {
-
-      @Override
-      public boolean apply(Endpoint input) {
-         return input.getVersionId().equals(apiVersion);
-      }
-
-   };
-
-   private final Predicate<Endpoint> versionAware = new Predicate<Endpoint>() {
-
-      @Override
-      public boolean apply(Endpoint input) {
-         return input.getVersionId() != null;
-      }
-
-   };
-
-   private final Predicate<Service> apiTypeEquals = new Predicate<Service>() {
-
-      @Override
-      public boolean apply(Service input) {
-         return input.getType().equals(apiType);
-      }
-
-   };
-
-   private static <K, V> void putIfPresent(K key, Optional<V> value, Builder<K, V> builder) {
-      if (value.isPresent())
-         builder.put(key, value.get());
-   }
-
-   @Override
-   public String toString() {
-      return "locationIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java
deleted file mode 100644
index bd794d2..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURIFromAccessForTypeAndVersion.java
+++ /dev/null
@@ -1,42 +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.keystone.v2_0.suppliers;
-
-import javax.inject.Inject;
-
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.functions.EndpointToRegion;
-import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierAdminURI;
-
-import com.google.common.base.Supplier;
-import com.google.inject.assistedinject.Assisted;
-
-public class RegionIdToAdminURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
-         RegionIdToAdminURISupplier {
-   @Inject
-   public RegionIdToAdminURIFromAccessForTypeAndVersion(Supplier<Access> access,
-            EndpointToSupplierAdminURI endpointToSupplierURI, EndpointToRegion endpointToRegion,
-            @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
-      super(access, endpointToSupplierURI, endpointToRegion, apiType, apiVersion);
-   }
-
-   @Override
-   public String toString() {
-      return "regionIdToAdminURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURISupplier.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURISupplier.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURISupplier.java
deleted file mode 100644
index 759c2b9..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToAdminURISupplier.java
+++ /dev/null
@@ -1,45 +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.keystone.v2_0.suppliers;
-
-import java.net.URI;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import org.jclouds.javax.annotation.Nullable;
-
-import com.google.common.base.Supplier;
-import com.google.inject.ImplementedBy;
-import com.google.inject.assistedinject.Assisted;
-
-@ImplementedBy(RegionIdToAdminURIFromAccessForTypeAndVersion.class)
-public interface RegionIdToAdminURISupplier extends Supplier<Map<String, Supplier<URI>>> {
-   interface Factory {
-      /**
-       * 
-       * @param apiType
-       *           type of the api, according to the provider. ex. {@code compute}
-       *           {@code object-store}
-       * @param apiVersion
-       *           version of the api, or null
-       * @return regions mapped to default uri
-       * @throws NoSuchElementException if the {@code apiType} is not present in the catalog
-       */
-      RegionIdToAdminURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType,
-               @Nullable @Assisted("apiVersion") String apiVersion) throws NoSuchElementException;
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java
deleted file mode 100644
index aff2814..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersion.java
+++ /dev/null
@@ -1,44 +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.keystone.v2_0.suppliers;
-
-import javax.inject.Inject;
-
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.location.suppliers.RegionIdToURISupplier;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.functions.EndpointToRegion;
-import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierURI;
-
-import com.google.common.base.Supplier;
-import com.google.inject.assistedinject.Assisted;
-
-public class RegionIdToURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
-         RegionIdToURISupplier {
-
-   @Inject
-   public RegionIdToURIFromAccessForTypeAndVersion(Supplier<Access> access,
-            EndpointToSupplierURI endpointToSupplierURI, EndpointToRegion endpointToRegion,
-            @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
-      super(access, endpointToSupplierURI, endpointToRegion, apiType, apiVersion);
-   }
-
-   @Override
-   public String toString() {
-      return "regionIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersion.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersion.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersion.java
deleted file mode 100644
index 41f936b..0000000
--- a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersion.java
+++ /dev/null
@@ -1,47 +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.keystone.v2_0.suppliers;
-
-import javax.inject.Inject;
-
-import org.jclouds.javax.annotation.Nullable;
-import org.jclouds.location.suppliers.ZoneIdToURISupplier;
-import org.jclouds.openstack.keystone.v2_0.domain.Access;
-import org.jclouds.openstack.keystone.v2_0.functions.EndpointToRegion;
-import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierURI;
-
-import com.google.common.base.Supplier;
-import com.google.inject.assistedinject.Assisted;
-
-public class ZoneIdToURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
-         ZoneIdToURISupplier {
-
-   @Inject
-   public ZoneIdToURIFromAccessForTypeAndVersion(
-            Supplier<Access> access,
-            // NOTE that in some services, the region is in fact the zone. temporarily, we need
-            // to use the region field, in this case.
-            EndpointToSupplierURI endpointToSupplierURI, EndpointToRegion endpointToZone,
-            @Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
-      super(access, endpointToSupplierURI, endpointToZone, apiType, apiVersion);
-   }
-
-   @Override
-   public String toString() {
-      return "zoneIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")";
-   }
-}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/7def8169/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/KeystoneApi.java
----------------------------------------------------------------------
diff --git a/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/KeystoneApi.java b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/KeystoneApi.java
new file mode 100644
index 0000000..6c2bca5
--- /dev/null
+++ b/apis/openstack-keystone/src/main/java/org/jclouds/openstack/keystone/v3/KeystoneApi.java
@@ -0,0 +1,35 @@
+/*
+ * 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.keystone.v3;
+
+import java.io.Closeable;
+
+import org.jclouds.openstack.keystone.v3.features.TokenApi;
+import org.jclouds.rest.annotations.Delegate;
+
+/**
+ * Provides access to the OpenStack Identity (Keystone) REST API.
+ */
+public interface KeystoneApi extends Closeable {
+
+   /**
+    * Provides access to Token features
+    */
+   @Delegate
+   TokenApi getTokenApi();
+
+}