mirror of https://github.com/apache/jclouds.git
Issue 815: refactored the 3 major features of keystone into separate clients. removed cyclic dependency needed to support keystone controlling keystones in other regions
This commit is contained in:
parent
a8b5c713a1
commit
d00e360d65
|
@ -23,6 +23,7 @@ import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.core.MediaType;
|
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.binders.BindAuthToJsonPayload;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
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.ApiAccessKeyCredentials;
|
||||||
|
@ -53,7 +54,7 @@ public interface AuthenticationAsyncClient {
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Path("/tokens")
|
@Path("/tokens")
|
||||||
@MapBinder(BindAuthToJsonPayload.class)
|
@MapBinder(BindAuthToJsonPayload.class)
|
||||||
ListenableFuture<Access> authenticateWithTenantNameAndCredentials(@PayloadParam("tenantName") String tenantName,
|
ListenableFuture<Access> authenticateWithTenantNameAndCredentials(@Nullable @PayloadParam("tenantName") String tenantName,
|
||||||
PasswordCredentials passwordCredentials);
|
PasswordCredentials passwordCredentials);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +65,7 @@ public interface AuthenticationAsyncClient {
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Path("/tokens")
|
@Path("/tokens")
|
||||||
@MapBinder(BindAuthToJsonPayload.class)
|
@MapBinder(BindAuthToJsonPayload.class)
|
||||||
ListenableFuture<Access> authenticateWithTenantIdAndCredentials(@PayloadParam("tenantId") String tenantId,
|
ListenableFuture<Access> authenticateWithTenantIdAndCredentials(@Nullable @PayloadParam("tenantId") String tenantId,
|
||||||
PasswordCredentials passwordCredentials);
|
PasswordCredentials passwordCredentials);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,7 +78,7 @@ public interface AuthenticationAsyncClient {
|
||||||
@MapBinder(BindAuthToJsonPayload.class)
|
@MapBinder(BindAuthToJsonPayload.class)
|
||||||
// TODO: is tenantName permanent? or should we switch to tenantId at some point. seems most tools
|
// TODO: is tenantName permanent? or should we switch to tenantId at some point. seems most tools
|
||||||
// still use tenantName
|
// still use tenantName
|
||||||
ListenableFuture<Access> authenticateWithTenantNameAndCredentials(@PayloadParam("tenantName") String tenantName,
|
ListenableFuture<Access> authenticateWithTenantNameAndCredentials(@Nullable @PayloadParam("tenantName") String tenantName,
|
||||||
ApiAccessKeyCredentials apiAccessKeyCredentials);
|
ApiAccessKeyCredentials apiAccessKeyCredentials);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,6 +89,6 @@ public interface AuthenticationAsyncClient {
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@Path("/tokens")
|
@Path("/tokens")
|
||||||
@MapBinder(BindAuthToJsonPayload.class)
|
@MapBinder(BindAuthToJsonPayload.class)
|
||||||
ListenableFuture<Access> authenticateWithTenantIdAndCredentials(@PayloadParam("tenantId") String tenantId,
|
ListenableFuture<Access> authenticateWithTenantIdAndCredentials(@Nullable @PayloadParam("tenantId") String tenantId,
|
||||||
ApiAccessKeyCredentials apiAccessKeyCredentials);
|
ApiAccessKeyCredentials apiAccessKeyCredentials);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.openstack.keystone.v2_0;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
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.ApiAccessKeyCredentials;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
|
import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
|
||||||
|
@ -42,26 +43,26 @@ public interface AuthenticationClient {
|
||||||
*
|
*
|
||||||
* @return access with token
|
* @return access with token
|
||||||
*/
|
*/
|
||||||
Access authenticateWithTenantNameAndCredentials(String tenantId, PasswordCredentials passwordCredentials);
|
Access authenticateWithTenantNameAndCredentials(@Nullable String tenantId, PasswordCredentials passwordCredentials);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticate to generate a token.
|
* Authenticate to generate a token.
|
||||||
*
|
*
|
||||||
* @return access with token
|
* @return access with token
|
||||||
*/
|
*/
|
||||||
Access authenticateWithTenantIdAndCredentials(String tenantId, PasswordCredentials passwordCredentials);
|
Access authenticateWithTenantIdAndCredentials(@Nullable String tenantId, PasswordCredentials passwordCredentials);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticate to generate a token.
|
* Authenticate to generate a token.
|
||||||
*
|
*
|
||||||
* @return access with token
|
* @return access with token
|
||||||
*/
|
*/
|
||||||
Access authenticateWithTenantNameAndCredentials(String tenantId, ApiAccessKeyCredentials passwordCredentials);
|
Access authenticateWithTenantNameAndCredentials(@Nullable String tenantId, ApiAccessKeyCredentials passwordCredentials);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticate to generate a token.
|
* Authenticate to generate a token.
|
||||||
*
|
*
|
||||||
* @return access with token
|
* @return access with token
|
||||||
*/
|
*/
|
||||||
Access authenticateWithTenantIdAndCredentials(String tenantId, ApiAccessKeyCredentials passwordCredentials);
|
Access authenticateWithTenantIdAndCredentials(@Nullable String tenantId, ApiAccessKeyCredentials passwordCredentials);
|
||||||
}
|
}
|
|
@ -18,12 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.keystone.v2_0;
|
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.v2_0.config.KeystoneProperties.SERVICE_TYPE;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.apis.ApiMetadata;
|
import org.jclouds.apis.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneRestClientModule;
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneRestClientModule;
|
||||||
import org.jclouds.openstack.v2_0.ServiceType;
|
import org.jclouds.openstack.v2_0.ServiceType;
|
||||||
|
@ -44,19 +46,18 @@ public class KeystoneApiMetadata extends BaseRestApiMetadata {
|
||||||
/** The serialVersionUID */
|
/** The serialVersionUID */
|
||||||
private static final long serialVersionUID = 6725672099385580694L;
|
private static final long serialVersionUID = 6725672099385580694L;
|
||||||
|
|
||||||
public static final TypeToken<RestContext<KeystoneClient, KeystoneAsyncClient>> CONTEXT_TOKEN = new TypeToken<RestContext<KeystoneClient, KeystoneAsyncClient>>() {
|
|
||||||
|
|
||||||
/** The serialVersionUID */
|
public static final TypeToken<RestContext<? extends KeystoneClient,? extends KeystoneAsyncClient>> CONTEXT_TOKEN = new TypeToken<RestContext<? extends KeystoneClient,? extends KeystoneAsyncClient>>() {
|
||||||
private static final long serialVersionUID = 3030344682235783904L;
|
private static final long serialVersionUID = -5070937833892503232L;
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Builder toBuilder() {
|
public Builder toBuilder() {
|
||||||
return new Builder().fromApiMetadata(this);
|
return (Builder) new Builder(getApi(), getAsyncApi()).fromApiMetadata(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeystoneApiMetadata() {
|
public KeystoneApiMetadata() {
|
||||||
this(new Builder());
|
this(new Builder(KeystoneClient.class, KeystoneAsyncClient.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected KeystoneApiMetadata(Builder builder) {
|
protected KeystoneApiMetadata(Builder builder) {
|
||||||
|
@ -67,14 +68,15 @@ public class KeystoneApiMetadata extends BaseRestApiMetadata {
|
||||||
Properties properties = BaseRestApiMetadata.defaultProperties();
|
Properties properties = BaseRestApiMetadata.defaultProperties();
|
||||||
// TODO: this doesn't actually do anything yet.
|
// TODO: this doesn't actually do anything yet.
|
||||||
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
||||||
|
properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
|
||||||
properties.put(SERVICE_TYPE, ServiceType.IDENTITY);
|
properties.put(SERVICE_TYPE, ServiceType.IDENTITY);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends BaseRestApiMetadata.Builder {
|
public static class Builder extends BaseRestApiMetadata.Builder {
|
||||||
|
|
||||||
protected Builder() {
|
protected Builder(Class<?> api, Class<?> asyncApi) {
|
||||||
super(KeystoneClient.class, KeystoneAsyncClient.class);
|
super(api, asyncApi);
|
||||||
id("openstack-keystone")
|
id("openstack-keystone")
|
||||||
.name("OpenStack Keystone Essex+ API")
|
.name("OpenStack Keystone Essex+ API")
|
||||||
.identityName("tenantId:user")
|
.identityName("tenantId:user")
|
||||||
|
|
|
@ -18,21 +18,22 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.keystone.v2_0;
|
package org.jclouds.openstack.keystone.v2_0;
|
||||||
|
|
||||||
import java.util.Set;
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
import org.jclouds.location.Region;
|
import org.jclouds.openstack.keystone.v2_0.features.TenantAsyncClient;
|
||||||
import org.jclouds.location.functions.RegionToEndpoint;
|
import org.jclouds.openstack.keystone.v2_0.features.TokenAsyncClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.features.AdminAsyncClient;
|
import org.jclouds.openstack.keystone.v2_0.features.UserAsyncClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.features.ServiceAsyncClient;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.functions.RegionToAdminEndpointURI;
|
|
||||||
import org.jclouds.rest.annotations.Delegate;
|
import org.jclouds.rest.annotations.Delegate;
|
||||||
import org.jclouds.rest.annotations.EndpointParam;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
import com.google.inject.Provides;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Openstack keystone resources via their REST API.
|
* Provides access to Openstack keystone resources via their REST API.
|
||||||
|
@ -42,20 +43,34 @@ import com.google.inject.Provides;
|
||||||
* @see <a href="http://keystone.openstack.org/" />
|
* @see <a href="http://keystone.openstack.org/" />
|
||||||
* @see KeystoneClient
|
* @see KeystoneClient
|
||||||
*/
|
*/
|
||||||
@Path("/v{" + Constants.PROPERTY_API_VERSION + "}")
|
|
||||||
public interface KeystoneAsyncClient {
|
public interface KeystoneAsyncClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the Region codes configured
|
* @see KeystoneClient#getApiMetadata()
|
||||||
*/
|
*/
|
||||||
@Provides
|
@GET
|
||||||
@Region
|
@SelectJson("version")
|
||||||
Set<String> getConfiguredRegions();
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/v{" + Constants.PROPERTY_API_VERSION + "}/")
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<ApiMetadata> getApiMetadata();
|
||||||
|
|
||||||
/** Provides asynchronous access to Identity user-accessible features */
|
/**
|
||||||
|
* @see KeystoneClient#getTokenClient()
|
||||||
|
*/
|
||||||
@Delegate
|
@Delegate
|
||||||
ServiceAsyncClient getServiceClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
TokenAsyncClient getTokenClient();
|
||||||
|
|
||||||
/** Provides asynchronous access to the KeyStone Admin API */
|
/**
|
||||||
|
* @see KeystoneClient#getUserClient()
|
||||||
|
*/
|
||||||
@Delegate
|
@Delegate
|
||||||
AdminAsyncClient getAdminClientForRegion(@EndpointParam(parser = RegionToAdminEndpointURI.class) @Nullable String region);
|
UserAsyncClient getUserClient();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see KeystoneClient#getTenantClient()
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
TenantAsyncClient getTenantClient();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,20 +18,14 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.keystone.v2_0;
|
package org.jclouds.openstack.keystone.v2_0;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
import org.jclouds.location.Region;
|
import org.jclouds.openstack.keystone.v2_0.features.TenantClient;
|
||||||
import org.jclouds.location.functions.RegionToEndpoint;
|
import org.jclouds.openstack.keystone.v2_0.features.TokenClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.features.AdminClient;
|
import org.jclouds.openstack.keystone.v2_0.features.UserClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.features.ServiceClient;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.functions.RegionToAdminEndpointURI;
|
|
||||||
import org.jclouds.rest.annotations.Delegate;
|
import org.jclouds.rest.annotations.Delegate;
|
||||||
import org.jclouds.rest.annotations.EndpointParam;
|
|
||||||
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides access to Openstack keystone resources via their REST API.
|
* Provides access to Openstack keystone resources via their REST API.
|
||||||
|
@ -39,22 +33,34 @@ import com.google.inject.Provides;
|
||||||
*
|
*
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
* @see <a href="http://keystone.openstack.org/" />
|
* @see <a href="http://keystone.openstack.org/" />
|
||||||
|
* @see KeystoneAsyncClient
|
||||||
*/
|
*/
|
||||||
@Timeout(duration = 10, timeUnit = TimeUnit.SECONDS)
|
@Timeout(duration = 10, timeUnit = TimeUnit.SECONDS)
|
||||||
public interface KeystoneClient {
|
public interface KeystoneClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the Region codes configured
|
* Discover API version information, links to documentation (PDF, HTML, WADL), and supported media types
|
||||||
|
*
|
||||||
|
* @return the requested information
|
||||||
*/
|
*/
|
||||||
@Provides
|
ApiMetadata getApiMetadata();
|
||||||
@Region
|
|
||||||
Set<String> getConfiguredRegions();
|
|
||||||
|
|
||||||
/** Provides synchronous access to Identity user-accessible features */
|
/**
|
||||||
|
* Provides synchronous access to Token features
|
||||||
|
*/
|
||||||
@Delegate
|
@Delegate
|
||||||
ServiceClient getServiceClientForRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
TokenClient getTokenClient();
|
||||||
|
|
||||||
/** Provides synchronous access to the KeyStone Admin API */
|
/**
|
||||||
|
* Provides synchronous access to User features
|
||||||
|
*/
|
||||||
@Delegate
|
@Delegate
|
||||||
AdminClient getAdminClientForRegion(@EndpointParam(parser = RegionToAdminEndpointURI.class) @Nullable String region);
|
UserClient getUserClient();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to Tenant features
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
TenantClient getTenantClient();
|
||||||
}
|
}
|
|
@ -29,14 +29,15 @@ import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.json.Json;
|
import org.jclouds.json.Json;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials;
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
|
|
||||||
import org.jclouds.rest.MapBinder;
|
import org.jclouds.rest.MapBinder;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.ImmutableMap.Builder;
|
import com.google.common.collect.ImmutableMap.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,11 +58,9 @@ public class BindAuthToJsonPayload extends BindToJsonPayload implements MapBinde
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addCredentialsInArgsOrNull(GeneratedHttpRequest<?> gRequest, Builder<String, Object> builder) {
|
protected void addCredentialsInArgsOrNull(GeneratedHttpRequest<?> gRequest, Builder<String, Object> builder) {
|
||||||
for (Object arg : gRequest.getArgs()) {
|
for (Object arg : Iterables.filter(gRequest.getArgs(), Predicates.notNull())) {
|
||||||
if (arg instanceof PasswordCredentials) {
|
if (arg.getClass().isAnnotationPresent(CredentialType.class)) {
|
||||||
builder.put("passwordCredentials", PasswordCredentials.class.cast(arg));
|
builder.put(arg.getClass().getAnnotation(CredentialType.class).value(), arg);
|
||||||
} else if (arg instanceof ApiAccessKeyCredentials) {
|
|
||||||
builder.put("apiAccessKeyCredentials", ApiAccessKeyCredentials.class.cast(arg));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,29 +18,25 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.keystone.v2_0.config;
|
package org.jclouds.openstack.keystone.v2_0.config;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import com.google.common.base.CaseFormat;
|
import javax.inject.Qualifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration properties and constants used in Keystone connections.
|
* @see CredentialTypes
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public enum CredentialType {
|
@Retention(value = RetentionPolicy.RUNTIME)
|
||||||
|
@Target(value = { ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||||
API_ACCESS_KEY_CREDENTIALS,
|
@Qualifier
|
||||||
|
public @interface CredentialType {
|
||||||
PASSWORD_CREDENTIALS;
|
/**
|
||||||
|
* @see CredentialTypes
|
||||||
@Override
|
*
|
||||||
public String toString() {
|
*/
|
||||||
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name());
|
String value();
|
||||||
}
|
|
||||||
|
|
||||||
public static CredentialType fromValue(String credentialType) {
|
|
||||||
return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(credentialType,
|
|
||||||
"credentialType")));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,9 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.keystone.v2_0.config;
|
package org.jclouds.openstack.keystone.v2_0.config;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Throwables.propagate;
|
import static com.google.common.base.Throwables.propagate;
|
||||||
import static org.jclouds.rest.config.BinderUtils.bindClientAndAsyncClient;
|
import static org.jclouds.rest.config.BinderUtils.bindClientAndAsyncClient;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
@ -45,10 +47,10 @@ import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
||||||
import org.jclouds.openstack.keystone.v2_0.functions.AuthenticateApiAccessKeyCredentials;
|
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.functions.AuthenticatePasswordCredentials;
|
||||||
import org.jclouds.openstack.keystone.v2_0.handlers.RetryOnRenew;
|
import org.jclouds.openstack.keystone.v2_0.handlers.RetryOnRenew;
|
||||||
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersionSupplier;
|
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.RegionIdToAdminURISupplier;
|
||||||
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToURIFromAccessForTypeAndVersionSupplier;
|
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToURIFromAccessForTypeAndVersion;
|
||||||
import org.jclouds.openstack.keystone.v2_0.suppliers.ZoneIdToURIFromAccessForTypeAndVersionSupplier;
|
import org.jclouds.openstack.keystone.v2_0.suppliers.ZoneIdToURIFromAccessForTypeAndVersion;
|
||||||
import org.jclouds.rest.annotations.ApiVersion;
|
import org.jclouds.rest.annotations.ApiVersion;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -56,8 +58,10 @@ import com.google.common.base.Supplier;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
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.AbstractModule;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
|
@ -77,17 +81,23 @@ public class KeystoneAuthenticationModule extends AbstractModule {
|
||||||
this.locationModule = locationModule;
|
this.locationModule = locationModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class KeystoneAuthenticationModuleForRegions extends KeystoneAuthenticationModule {
|
||||||
|
public KeystoneAuthenticationModuleForRegions() {
|
||||||
|
super(new RegionModule());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Module forRegions() {
|
public static Module forRegions() {
|
||||||
return new KeystoneAuthenticationModule(new RegionModule());
|
return new KeystoneAuthenticationModuleForRegions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class RegionModule extends AbstractModule {
|
public static class RegionModule extends AbstractModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
|
install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
|
||||||
RegionIdToURIFromAccessForTypeAndVersionSupplier.class).build(RegionIdToURISupplier.Factory.class));
|
RegionIdToURIFromAccessForTypeAndVersion.class).build(RegionIdToURISupplier.Factory.class));
|
||||||
install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
|
install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
|
||||||
RegionIdToAdminURIFromAccessForTypeAndVersionSupplier.class).build(RegionIdToAdminURISupplier.Factory.class));
|
RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
|
||||||
// dynamically build the region list as opposed to from properties
|
// dynamically build the region list as opposed to from properties
|
||||||
bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class);
|
bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class);
|
||||||
}
|
}
|
||||||
|
@ -102,13 +112,14 @@ public class KeystoneAuthenticationModule extends AbstractModule {
|
||||||
return factory.createForApiTypeAndVersion(serviceType, apiVersion);
|
return factory.createForApiTypeAndVersion(serviceType, apiVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// supply the region to id to AdminURL map from keystone, based on the servicetype and api version in
|
// supply the region to id to AdminURL map from keystone, based on the servicetype and api
|
||||||
|
// version in
|
||||||
// config
|
// config
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected RegionIdToAdminURISupplier provideRegionIdToAdminURISupplierForApiVersion(
|
protected RegionIdToAdminURISupplier provideRegionIdToAdminURISupplierForApiVersion(
|
||||||
@Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
|
@Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion,
|
||||||
RegionIdToAdminURISupplier.Factory factory) {
|
RegionIdToAdminURISupplier.Factory factory) {
|
||||||
return factory.createForApiTypeAndVersion(serviceType, apiVersion);
|
return factory.createForApiTypeAndVersion(serviceType, apiVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +129,7 @@ public class KeystoneAuthenticationModule extends AbstractModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new FactoryModuleBuilder().implement(ZoneIdToURISupplier.class,
|
install(new FactoryModuleBuilder().implement(ZoneIdToURISupplier.class,
|
||||||
ZoneIdToURIFromAccessForTypeAndVersionSupplier.class).build(ZoneIdToURISupplier.Factory.class));
|
ZoneIdToURIFromAccessForTypeAndVersion.class).build(ZoneIdToURISupplier.Factory.class));
|
||||||
// dynamically build the zone list as opposed to from properties
|
// dynamically build the zone list as opposed to from properties
|
||||||
bind(ZoneIdsSupplier.class).to(ZoneIdsFromZoneIdToURIKeySet.class);
|
bind(ZoneIdsSupplier.class).to(ZoneIdsFromZoneIdToURIKeySet.class);
|
||||||
}
|
}
|
||||||
|
@ -135,18 +146,27 @@ public class KeystoneAuthenticationModule extends AbstractModule {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class KeystoneAuthenticationModuleForZones extends KeystoneAuthenticationModule {
|
||||||
|
public KeystoneAuthenticationModuleForZones() {
|
||||||
|
super(new ZoneModule());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Module forZones() {
|
public static Module forZones() {
|
||||||
return new KeystoneAuthenticationModule(new ZoneModule());
|
return new KeystoneAuthenticationModuleForZones();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
|
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class);
|
||||||
bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class);
|
bindAuthenticationClient();
|
||||||
// ServiceClient is used directly for filters and retry handlers, so let's bind it
|
install(locationModule);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void bindAuthenticationClient() {
|
||||||
|
// AuthenticationClient is used directly for filters and retry handlers, so let's bind it
|
||||||
// explicitly
|
// explicitly
|
||||||
bindClientAndAsyncClient(binder(), AuthenticationClient.class, AuthenticationAsyncClient.class);
|
bindClientAndAsyncClient(binder(), AuthenticationClient.class, AuthenticationAsyncClient.class);
|
||||||
install(locationModule);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,41 +184,25 @@ public class KeystoneAuthenticationModule extends AbstractModule {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static class CredentialTypeFromPropertyOrDefault implements javax.inject.Provider<CredentialType> {
|
protected Map<String, Function<Credentials, Access>> authenticationMethods(Injector i) {
|
||||||
/**
|
Builder<Function<Credentials, Access>> fns = ImmutableSet.<Function<Credentials, Access>> builder();
|
||||||
* use optional injection to supply a default value for credential type. so that we don't have
|
fns.add(i.getInstance(AuthenticatePasswordCredentials.class));
|
||||||
* to set a default property.
|
fns.add(i.getInstance(AuthenticateApiAccessKeyCredentials.class));
|
||||||
*/
|
return CredentialTypes.indexByCredentialType(fns.build());
|
||||||
@Inject(optional = true)
|
|
||||||
@Named(KeystoneProperties.CREDENTIAL_TYPE)
|
|
||||||
String credentialType = CredentialType.PASSWORD_CREDENTIALS.toString();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CredentialType get() {
|
|
||||||
return CredentialType.fromValue(credentialType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Function<Credentials, Access> authenticationMethodForCredentialType(CredentialType credentialType,
|
protected Function<Credentials, Access> authenticationMethodForCredentialType(
|
||||||
AuthenticatePasswordCredentials authenticatePasswordCredentials,
|
@Named(KeystoneProperties.CREDENTIAL_TYPE) String credentialType,
|
||||||
AuthenticateApiAccessKeyCredentials authenticateApiAccessKeyCredentials) {
|
Map<String, Function<Credentials, Access>> authenticationMethods) {
|
||||||
Function<Credentials, Access> authMethod;
|
checkArgument(authenticationMethods.containsKey(credentialType), "credential type %s not in supported list: %s",
|
||||||
switch (credentialType) {
|
credentialType, authenticationMethods.keySet());
|
||||||
case PASSWORD_CREDENTIALS:
|
|
||||||
authMethod = authenticatePasswordCredentials;
|
|
||||||
break;
|
|
||||||
case API_ACCESS_KEY_CREDENTIALS:
|
|
||||||
authMethod = authenticateApiAccessKeyCredentials;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("credential type not supported: " + credentialType);
|
|
||||||
}
|
|
||||||
// regardless of how we authenticate, we should retry if there is a timeout exception logging
|
// regardless of how we authenticate, we should retry if there is a timeout exception logging
|
||||||
// in.
|
// in.
|
||||||
return new RetryOnTimeOutExceptionFunction<Credentials, Access>(authMethod);
|
return new RetryOnTimeOutExceptionFunction<Credentials, Access>(authenticationMethods.get(credentialType));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: what is the timeout of the session token? modify default accordingly
|
// TODO: what is the timeout of the session token? modify default accordingly
|
||||||
|
|
|
@ -36,7 +36,7 @@ public interface KeystoneProperties {
|
||||||
* <li>passwordCredentials</li>
|
* <li>passwordCredentials</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @see CredentialType
|
* @see CredentialTypes
|
||||||
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_Service_API_Client_Operations.html"
|
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/POST_authenticate_v2.0_tokens_Service_API_Client_Operations.html"
|
||||||
* />
|
* />
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,15 +26,19 @@ import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.openstack.keystone.v2_0.KeystoneAsyncClient;
|
import org.jclouds.openstack.keystone.v2_0.KeystoneAsyncClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.KeystoneClient;
|
import org.jclouds.openstack.keystone.v2_0.KeystoneClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.features.AdminAsyncClient;
|
import org.jclouds.openstack.keystone.v2_0.features.TenantAsyncClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.features.AdminClient;
|
import org.jclouds.openstack.keystone.v2_0.features.TenantClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.features.ServiceAsyncClient;
|
import org.jclouds.openstack.keystone.v2_0.features.TokenAsyncClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.features.ServiceClient;
|
import org.jclouds.openstack.keystone.v2_0.features.TokenClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.features.UserAsyncClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.features.UserClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.handlers.KeystoneErrorHandler;
|
import org.jclouds.openstack.keystone.v2_0.handlers.KeystoneErrorHandler;
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.reflect.TypeToken;
|
||||||
|
import com.google.inject.util.Modules;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the Keystone connection.
|
* Configures the Keystone connection.
|
||||||
|
@ -42,15 +46,22 @@ import com.google.common.collect.ImmutableMap;
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
*/
|
*/
|
||||||
@ConfiguresRestClient
|
@ConfiguresRestClient
|
||||||
public class KeystoneRestClientModule extends RestClientModule<KeystoneClient, KeystoneAsyncClient> {
|
public class KeystoneRestClientModule<S extends KeystoneClient, A extends KeystoneAsyncClient> extends RestClientModule<S, A> {
|
||||||
|
|
||||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
|
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
|
||||||
.put(ServiceClient.class, ServiceAsyncClient.class)
|
.put(TokenClient.class, TokenAsyncClient.class)
|
||||||
.put(AdminClient.class, AdminAsyncClient.class)
|
.put(UserClient.class, UserAsyncClient.class)
|
||||||
|
.put(TenantClient.class, TenantAsyncClient.class)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public KeystoneRestClientModule() {
|
public KeystoneRestClientModule() {
|
||||||
super(DELEGATE_MAP);
|
super((TypeToken) TypeToken.of(KeystoneClient.class), (TypeToken) TypeToken.of(KeystoneAsyncClient.class), DELEGATE_MAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected KeystoneRestClientModule(TypeToken<S> syncClientType, TypeToken<A> asyncClientType,
|
||||||
|
Map<Class<?>, Class<?>> sync2Async) {
|
||||||
|
super(syncClientType, asyncClientType, sync2Async);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,10 +72,7 @@ public class KeystoneRestClientModule extends RestClientModule<KeystoneClient, K
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void installLocations() {
|
protected void installLocations() {
|
||||||
// TODO: select this from KeystoneProperties.VERSION; note you select from
|
install(new KeystoneAuthenticationModule(Modules.EMPTY_MODULE));
|
||||||
// a guice provided property, so it will have to come from somewhere else, maybe we move
|
|
||||||
// this to the the ContextBuilder
|
|
||||||
install(KeystoneAuthenticationModule.forRegions());
|
|
||||||
super.installLocations();
|
super.installLocations();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,9 @@ import static com.google.common.base.Objects.equal;
|
||||||
import static com.google.common.base.Objects.toStringHelper;
|
import static com.google.common.base.Objects.toStringHelper;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +35,7 @@ import com.google.common.base.Objects;
|
||||||
* />
|
* />
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@CredentialType(CredentialTypes.API_ACCESS_KEY_CREDENTIALS)
|
||||||
public class ApiAccessKeyCredentials {
|
public class ApiAccessKeyCredentials {
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
|
|
|
@ -105,15 +105,31 @@ public class ApiMetadata extends Resource {
|
||||||
private String status;
|
private String status;
|
||||||
@Nullable
|
@Nullable
|
||||||
private Date updated;
|
private Date updated;
|
||||||
|
|
||||||
|
|
||||||
|
// dealing with the goofy structure with "values" holder noted here
|
||||||
|
// http://docs.openstack.org/api/openstack-identity-service/2.0/content/Versions-d1e472.html
|
||||||
|
// if they change this to not be a value holder, we'll probably need to write a custom
|
||||||
|
// deserializer.
|
||||||
|
private static class MediaTypesHolder {
|
||||||
|
private Set<MediaType> values = ImmutableSet.of();
|
||||||
|
|
||||||
|
private MediaTypesHolder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private MediaTypesHolder(Set<MediaType> mediaTypes) {
|
||||||
|
this.values = ImmutableSet.copyOf(checkNotNull(mediaTypes, "mediaTypes"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedName(value="media-types")
|
@SerializedName(value="media-types")
|
||||||
@Nullable
|
private MediaTypesHolder mediaTypes = new MediaTypesHolder();
|
||||||
private Set<MediaType> mediaTypes = ImmutableSet.of();
|
|
||||||
|
|
||||||
protected ApiMetadata(Builder<?> builder) {
|
protected ApiMetadata(Builder<?> builder) {
|
||||||
super(builder);
|
super(builder);
|
||||||
this.status = checkNotNull(builder.status, "status");
|
this.status = checkNotNull(builder.status, "status");
|
||||||
this.updated = checkNotNull(builder.updated, "updated");
|
this.updated = checkNotNull(builder.updated, "updated");
|
||||||
this.mediaTypes = ImmutableSet.copyOf(checkNotNull(builder.mediaTypes, "mediaTypes"));
|
this.mediaTypes = new MediaTypesHolder(builder.mediaTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,12 +147,12 @@ public class ApiMetadata extends Resource {
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public Set<MediaType> getMediaTypes() {
|
public Set<MediaType> getMediaTypes() {
|
||||||
return Collections.unmodifiableSet(this.mediaTypes);
|
return Collections.unmodifiableSet(this.mediaTypes.values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(status, updated, mediaTypes);
|
return Objects.hashCode(status, updated, mediaTypes.values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -146,14 +162,14 @@ public class ApiMetadata extends Resource {
|
||||||
ApiMetadata that = ApiMetadata.class.cast(obj);
|
ApiMetadata that = ApiMetadata.class.cast(obj);
|
||||||
return super.equals(that) && Objects.equal(this.status, that.status)
|
return super.equals(that) && Objects.equal(this.status, that.status)
|
||||||
&& Objects.equal(this.updated, that.updated)
|
&& Objects.equal(this.updated, that.updated)
|
||||||
&& Objects.equal(this.mediaTypes, that.mediaTypes);
|
&& Objects.equal(this.mediaTypes.values, that.mediaTypes.values);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
protected ToStringHelper string() {
|
||||||
return super.string()
|
return super.string()
|
||||||
.add("status", status)
|
.add("status", status)
|
||||||
.add("updated", updated)
|
.add("updated", updated)
|
||||||
.add("mediaTypes", mediaTypes);
|
.add("mediaTypes", mediaTypes.values);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -57,6 +57,8 @@ public class Endpoint implements Comparable<Endpoint> {
|
||||||
protected URI internalURL;
|
protected URI internalURL;
|
||||||
protected URI adminURL;
|
protected URI adminURL;
|
||||||
protected String tenantId;
|
protected String tenantId;
|
||||||
|
protected URI versionInfo;
|
||||||
|
protected URI versionList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Endpoint#getVersionId()
|
* @see Endpoint#getVersionId()
|
||||||
|
@ -106,13 +108,30 @@ public class Endpoint implements Comparable<Endpoint> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Endpoint#getVersionInfo()
|
||||||
|
*/
|
||||||
|
public Builder versionInfo(URI versionInfo) {
|
||||||
|
this.versionInfo = checkNotNull(versionInfo, "versionInfo");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Endpoint#getVersionList()
|
||||||
|
*/
|
||||||
|
public Builder versionList(URI versionList) {
|
||||||
|
this.versionList = checkNotNull(versionList, "versionList");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Endpoint build() {
|
public Endpoint build() {
|
||||||
return new Endpoint(versionId, region, publicURL, internalURL, adminURL, tenantId);
|
return new Endpoint(versionId, region, publicURL, internalURL, adminURL, tenantId, versionInfo, versionList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder fromEndpoint(Endpoint from) {
|
public Builder fromEndpoint(Endpoint from) {
|
||||||
return versionId(from.getVersionId()).region(from.getRegion()).publicURL(from.getPublicURL()).internalURL(
|
return versionId(from.getVersionId()).region(from.getRegion()).publicURL(from.getPublicURL()).internalURL(
|
||||||
from.getInternalURL()).tenantId(from.getTenantId());
|
from.getInternalURL()).tenantId(from.getTenantId()).versionInfo(from.getVersionInfo()).versionList(
|
||||||
|
from.getVersionList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,35 +149,41 @@ public class Endpoint implements Comparable<Endpoint> {
|
||||||
protected URI publicURL;
|
protected URI publicURL;
|
||||||
protected URI internalURL;
|
protected URI internalURL;
|
||||||
protected URI adminURL;
|
protected URI adminURL;
|
||||||
|
protected URI versionInfo;
|
||||||
|
protected URI versionList;
|
||||||
|
|
||||||
// renamed half-way through
|
// renamed half-way through
|
||||||
@Deprecated
|
@Deprecated
|
||||||
protected String tenantName;
|
protected String tenantName;
|
||||||
protected String tenantId;
|
protected String tenantId;
|
||||||
|
|
||||||
protected Endpoint(String versionId, String region, @Nullable URI publicURL, @Nullable URI internalURL,
|
protected Endpoint(@Nullable String versionId, @Nullable String region, @Nullable URI publicURL, @Nullable URI internalURL,
|
||||||
@Nullable URI adminURL, @Nullable String tenantId) {
|
@Nullable URI adminURL, @Nullable String tenantId, @Nullable URI versionInfo, @Nullable URI versionList) {
|
||||||
this.versionId = checkNotNull(versionId, "versionId");
|
this.versionId = versionId;
|
||||||
this.region = checkNotNull(region, "region");
|
this.region = region;
|
||||||
this.publicURL = publicURL;
|
this.publicURL = publicURL;
|
||||||
this.internalURL = internalURL;
|
this.internalURL = internalURL;
|
||||||
this.adminURL = adminURL;
|
this.adminURL = adminURL;
|
||||||
this.tenantId = tenantId;
|
this.tenantId = tenantId;
|
||||||
|
this.versionInfo = versionInfo;
|
||||||
|
this.versionList = versionList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When provversionIding an ID, it is assumed that the endpoint exists in the current OpenStack
|
* When providing an ID, it is assumed that the endpoint exists in the current OpenStack
|
||||||
* deployment
|
* deployment
|
||||||
*
|
*
|
||||||
* @return the versionId of the endpoint in the current OpenStack deployment
|
* @return the versionId of the endpoint in the current OpenStack deployment, or null if not specified
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public String getVersionId() {
|
public String getVersionId() {
|
||||||
return versionId != null ? versionId : id;
|
return versionId != null ? versionId : id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the region of the endpoint
|
* @return the region of the endpoint, or null if not specified
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public String getRegion() {
|
public String getRegion() {
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
@ -195,6 +220,20 @@ public class Endpoint implements Comparable<Endpoint> {
|
||||||
return tenantId != null ? tenantId : tenantName;
|
return tenantId != null ? tenantId : tenantName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public URI getVersionInfo() {
|
||||||
|
return versionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public URI getVersionList() {
|
||||||
|
return versionList;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
if (this == object) {
|
if (this == object) {
|
||||||
|
@ -216,8 +255,9 @@ public class Endpoint implements Comparable<Endpoint> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return toStringHelper("").add("versionId", getVersionId()).add("region", region).add("publicURL", publicURL).add("internalURL",
|
return toStringHelper("").add("versionId", getVersionId()).add("region", region).add("publicURL", publicURL).add(
|
||||||
internalURL).add("adminURL", adminURL).add("tenantId", getTenantId()).toString();
|
"internalURL", internalURL).add("adminURL", adminURL).add("tenantId", getTenantId()).add("versionInfo",
|
||||||
|
versionInfo).add("versionList", versionList).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,9 @@ import static com.google.common.base.Objects.equal;
|
||||||
import static com.google.common.base.Objects.toStringHelper;
|
import static com.google.common.base.Objects.toStringHelper;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialType;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,6 +35,7 @@ import com.google.common.base.Objects;
|
||||||
* />
|
* />
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@CredentialType(CredentialTypes.PASSWORD_CREDENTIALS)
|
||||||
public class PasswordCredentials {
|
public class PasswordCredentials {
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
|
|
|
@ -53,6 +53,7 @@ public class Role implements Comparable<Role> {
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
protected String id;
|
protected String id;
|
||||||
protected String name;
|
protected String name;
|
||||||
|
protected String description;
|
||||||
protected String serviceId;
|
protected String serviceId;
|
||||||
protected String tenantId;
|
protected String tenantId;
|
||||||
|
|
||||||
|
@ -72,6 +73,14 @@ public class Role implements Comparable<Role> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Role#getDescription()
|
||||||
|
*/
|
||||||
|
public Builder description(String description) {
|
||||||
|
this.description = checkNotNull(description, "description");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Role#getServiceId()
|
* @see Role#getServiceId()
|
||||||
*/
|
*/
|
||||||
|
@ -89,11 +98,11 @@ public class Role implements Comparable<Role> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Role build() {
|
public Role build() {
|
||||||
return new Role(id, name, serviceId, tenantId);
|
return new Role(id, name, description, serviceId, tenantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder fromRole(Role from) {
|
public Builder fromRole(Role from) {
|
||||||
return id(from.getId()).name(from.getName()).serviceId(from.getServiceId()).tenantId(from.getTenantId());
|
return id(from.getId()).name(from.getName()).description(from.getName()).serviceId(from.getServiceId()).tenantId(from.getTenantId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,15 +114,17 @@ public class Role implements Comparable<Role> {
|
||||||
|
|
||||||
protected String id;
|
protected String id;
|
||||||
protected String name;
|
protected String name;
|
||||||
|
protected String description;
|
||||||
protected String serviceId;
|
protected String serviceId;
|
||||||
// renamed half-way through
|
// renamed half-way through
|
||||||
@Deprecated
|
@Deprecated
|
||||||
protected String tenantName;
|
protected String tenantName;
|
||||||
protected String tenantId;
|
protected String tenantId;
|
||||||
|
|
||||||
protected Role(String id, String name, @Nullable String serviceId, @Nullable String tenantId) {
|
protected Role(String id, String name, @Nullable String description, @Nullable String serviceId, @Nullable String tenantId) {
|
||||||
this.id = checkNotNull(id, "id");
|
this.id = checkNotNull(id, "id");
|
||||||
this.name = checkNotNull(name, "name");
|
this.name = checkNotNull(name, "name");
|
||||||
|
this.description = description;
|
||||||
this.serviceId = serviceId;
|
this.serviceId = serviceId;
|
||||||
this.tenantId = tenantId;
|
this.tenantId = tenantId;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +145,14 @@ public class Role implements Comparable<Role> {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the description of the role
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the service id of the role or null, if not present
|
* @return the service id of the role or null, if not present
|
||||||
*/
|
*/
|
||||||
|
@ -171,7 +190,7 @@ public class Role implements Comparable<Role> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return toStringHelper("").add("id", id).add("name", name).add("serviceId", serviceId).add("tenantId", getTenantId())
|
return toStringHelper("").add("id", id).add("name", name).add("description", description).add("serviceId", serviceId).add("tenantId", getTenantId())
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,177 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.features;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
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.QueryParam;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
|
||||||
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.rest.annotations.ExceptionParser;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
import org.jclouds.rest.annotations.SkipEncoding;
|
|
||||||
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
|
||||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
|
||||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides asynchronous access to Admin via their REST API.
|
|
||||||
* <p/>
|
|
||||||
*
|
|
||||||
* @see AdminClient
|
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Admin_API_Service_Developer_Operations-d1e1356.html"
|
|
||||||
* />
|
|
||||||
* @author Adam Lowe
|
|
||||||
*/
|
|
||||||
@SkipEncoding({ '/', '=' })
|
|
||||||
public interface AdminAsyncClient {
|
|
||||||
/**
|
|
||||||
* @see AdminClient#getApiMetadata()
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@SelectJson("version")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/")
|
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<ApiMetadata> getApiMetadata();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see AdminClient#listTenants()
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@SelectJson("tenants")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/tenants")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<Set<Tenant>> listTenants();
|
|
||||||
|
|
||||||
/** @see AdminClient#getToken(String) */
|
|
||||||
@GET
|
|
||||||
@SelectJson("token")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/tokens/{token}")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<Token> getToken(@PathParam("token") String token);
|
|
||||||
|
|
||||||
/** @see AdminClient#getUserOfToken(String) */
|
|
||||||
@GET
|
|
||||||
@SelectJson("user")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/tokens/{token}")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<User> getUserOfToken(@PathParam("token") String token);
|
|
||||||
|
|
||||||
/** @see AdminClient#checkTokenIsValid(String) */
|
|
||||||
@HEAD
|
|
||||||
@Path("/tokens/{token}")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<Boolean> checkTokenIsValid(@PathParam("token") String token);
|
|
||||||
|
|
||||||
/** @see AdminClient#getEndpointsForToken(String) */
|
|
||||||
@GET
|
|
||||||
@SelectJson("endpoints")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/tokens/{token}/endpoints")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<Set<Endpoint>> getEndpointsForToken(@PathParam("token") String token);
|
|
||||||
|
|
||||||
/** @see AdminClient#getTenant(String) */
|
|
||||||
@GET
|
|
||||||
@SelectJson("tenant")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/tenants/{tenantId}")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<Tenant> getTenant(@PathParam("tenantId") String tenantId);
|
|
||||||
|
|
||||||
/** @see AdminClient#getTenantByName(String) */
|
|
||||||
@GET
|
|
||||||
@SelectJson("tenant")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/tenants")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<Tenant> getTenantByName(@QueryParam("name") String tenantName);
|
|
||||||
|
|
||||||
/** @see AdminClient#listUsers() */
|
|
||||||
@GET
|
|
||||||
@SelectJson("users")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/users")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<Set<User>> listUsers();
|
|
||||||
|
|
||||||
/** @see AdminClient#getUser(String) */
|
|
||||||
@GET
|
|
||||||
@SelectJson("user")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/users/{userId}")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<User> getUser(@PathParam("userId") String userId);
|
|
||||||
|
|
||||||
/** @see AdminClient#getUserByName(String) */
|
|
||||||
@GET
|
|
||||||
@SelectJson("user")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/users")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<User> getUserByName(@QueryParam("name") String userName);
|
|
||||||
|
|
||||||
/** @see AdminClient#listRolesOfUser(String) */
|
|
||||||
@GET
|
|
||||||
@SelectJson("roles")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/users/{userId}/roles")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<Set<Role>> listRolesOfUser(@PathParam("userId") String userId);
|
|
||||||
|
|
||||||
/** @see AdminClient#listRolesOfUserOnTenant(String, String) */
|
|
||||||
@GET
|
|
||||||
@SelectJson("roles")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/tenants/{tenantId}/users/{userId}/roles")
|
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<Set<Role>> listRolesOfUserOnTenant(@PathParam("userId") String userId, @PathParam("tenantId") String tenantId);
|
|
||||||
}
|
|
|
@ -1,145 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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.features;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Token;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides synchronous access to the KeyStone Admin API.
|
|
||||||
* <p/>
|
|
||||||
*
|
|
||||||
* @author Adam Lowe
|
|
||||||
* @see AdminAsyncClient
|
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Admin_API_Service_Developer_Operations-d1e1356.html"
|
|
||||||
* />
|
|
||||||
*/
|
|
||||||
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
|
||||||
public interface AdminClient {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Discover API version information, links to documentation (PDF, HTML, WADL), and supported media types
|
|
||||||
*
|
|
||||||
* @return the requested information
|
|
||||||
*/
|
|
||||||
ApiMetadata getApiMetadata();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The operation returns a list of tenants which the current token provides access to.
|
|
||||||
*/
|
|
||||||
Set<Tenant> listTenants();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve information about a tenant, by tenant ID
|
|
||||||
*
|
|
||||||
* @return the information about the tenant
|
|
||||||
*/
|
|
||||||
Tenant getTenant(String tenantId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve information about a tenant, by tenant name
|
|
||||||
* <p/>
|
|
||||||
* NOTE: currently not working in openstack ( https://bugs.launchpad.net/keystone/+bug/956687 )
|
|
||||||
*
|
|
||||||
* @return the information about the tenant
|
|
||||||
*/
|
|
||||||
Tenant getTenantByName(String tenantName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate a token and, if it is valid, return access information regarding the tenant (though not the service catalog)/
|
|
||||||
*
|
|
||||||
* @return the requested information
|
|
||||||
*/
|
|
||||||
Token getToken(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
|
|
||||||
*/
|
|
||||||
User getUserOfToken(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
|
|
||||||
*/
|
|
||||||
Boolean checkTokenIsValid(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
|
|
||||||
*/
|
|
||||||
Set<Endpoint> getEndpointsForToken(String token);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the list of users
|
|
||||||
* <p/>
|
|
||||||
* NOTE: this method is not in API documentation for keystone, but does work
|
|
||||||
*
|
|
||||||
* @return the list of users
|
|
||||||
*/
|
|
||||||
Set<User> listUsers();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve information about a user, by user ID
|
|
||||||
*
|
|
||||||
* @return the information about the user
|
|
||||||
*/
|
|
||||||
User getUser(String userId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve information about a user, by user name
|
|
||||||
* <p/>
|
|
||||||
* NOTE: currently not working in openstack ( https://bugs.launchpad.net/keystone/+bug/956687 )
|
|
||||||
*
|
|
||||||
* @return the information about the user
|
|
||||||
*/
|
|
||||||
User getUserByName(String userName);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the list of global roles associated with a specific user (excludes tenant roles).
|
|
||||||
* <p/>
|
|
||||||
* NOTE: Broken in openstack ( https://bugs.launchpad.net/keystone/+bug/933565 )
|
|
||||||
*
|
|
||||||
* @return the set of Roles granted to the user
|
|
||||||
*/
|
|
||||||
Set<Role> listRolesOfUser(String userId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List the roles a user has been granted on a specific tenant
|
|
||||||
*
|
|
||||||
* @return the set of roles
|
|
||||||
*/
|
|
||||||
Set<Role> listRolesOfUserOnTenant(String userId, String tenantId);
|
|
||||||
|
|
||||||
}
|
|
|
@ -23,9 +23,11 @@ import java.util.Set;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
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.filters.AuthenticateRequest;
|
||||||
import org.jclouds.rest.annotations.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
|
@ -38,28 +40,21 @@ import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides asynchronous access to Service via their REST API.
|
* Provides asynchronous access to Tenant via their REST API.
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @see ServiceClient
|
* @see TenantClient
|
||||||
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Client_Operations.html"
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Tenant_Operations.html"
|
||||||
* />
|
* />
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
*/
|
*/
|
||||||
@SkipEncoding({ '/', '=' })
|
@Path("/v{" + Constants.PROPERTY_API_VERSION + "}")
|
||||||
public interface ServiceAsyncClient {
|
@SkipEncoding( { '/', '=' })
|
||||||
/**
|
public interface TenantAsyncClient {
|
||||||
* @see ServiceClient#getApiMetadata()
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@SelectJson("version")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@Path("/")
|
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<ApiMetadata> getApiMetadata();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see ServiceClient#listTenants()
|
* @see TenantClient#list()
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@SelectJson("tenants")
|
@SelectJson("tenants")
|
||||||
|
@ -67,5 +62,24 @@ public interface ServiceAsyncClient {
|
||||||
@Path("/tenants")
|
@Path("/tenants")
|
||||||
@RequestFilters(AuthenticateRequest.class)
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
ListenableFuture<Set<Tenant>> listTenants();
|
ListenableFuture<Set<Tenant>> list();
|
||||||
|
|
||||||
|
/** @see TenantClient#get(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("tenant")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tenants/{tenantId}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Tenant> get(@PathParam("tenantId") String tenantId);
|
||||||
|
|
||||||
|
/** @see TenantClient#getByName(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("tenant")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tenants")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Tenant> getByName(@QueryParam("name") String tenantName);
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,30 +22,39 @@ import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides synchronous access to the KeyStone Service API.
|
* Provides synchronous access to the KeyStone Tenant API.
|
||||||
* <p/>
|
* <p/>
|
||||||
*
|
*
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
* @see ServiceAsyncClient
|
* @see TenantAsyncClient
|
||||||
* @see <a href="http://docs.openstack.org/api/openstack-identity-service/2.0/content/Service_API_Client_Operations.html"
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Tenant_Operations.html"
|
||||||
* />
|
* />
|
||||||
*/
|
*/
|
||||||
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||||
public interface ServiceClient {
|
public interface TenantClient {
|
||||||
|
|
||||||
/**
|
|
||||||
* Discover API version information, links to documentation (PDF, HTML, WADL), and supported media types
|
|
||||||
*
|
|
||||||
* @return the requested information
|
|
||||||
*/
|
|
||||||
ApiMetadata getApiMetadata();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The operation returns a list of tenants which the current token provides access to.
|
* The operation returns a list of tenants which the current token provides access to.
|
||||||
*/
|
*/
|
||||||
Set<Tenant> listTenants();
|
Set<Tenant> list();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a tenant, by tenant ID
|
||||||
|
*
|
||||||
|
* @return the information about the tenant
|
||||||
|
*/
|
||||||
|
Tenant get(String tenantId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a tenant, by tenant name
|
||||||
|
* <p/>
|
||||||
|
* NOTE: currently not working in openstack ( https://bugs.launchpad.net/keystone/+bug/956687 )
|
||||||
|
*
|
||||||
|
* @return the information about the tenant
|
||||||
|
*/
|
||||||
|
Tenant getByName(String tenantName);
|
||||||
}
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.features;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
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.Constants;
|
||||||
|
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.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Token via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see TokenClient
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Token_Operations.html"
|
||||||
|
* />
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Path("/v{" + Constants.PROPERTY_API_VERSION + "}")
|
||||||
|
@SkipEncoding({ '/', '=' })
|
||||||
|
public interface TokenAsyncClient {
|
||||||
|
|
||||||
|
|
||||||
|
/** @see TokenClient#get(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("token")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tokens/{token}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Token> get(@PathParam("token") String token);
|
||||||
|
|
||||||
|
/** @see TokenClient#getUserOfToken(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("user")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tokens/{token}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<User> getUserOfToken(@PathParam("token") String token);
|
||||||
|
|
||||||
|
/** @see TokenClient#isValid(String) */
|
||||||
|
@HEAD
|
||||||
|
@Path("/tokens/{token}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnFalseOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Boolean> isValid(@PathParam("token") String token);
|
||||||
|
|
||||||
|
/** @see TokenClient#listEndpointsForToken(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("endpoints")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tokens/{token}/endpoints")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Endpoint>> listEndpointsForToken(@PathParam("token") String token);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.features;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
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 com.google.common.annotations.Beta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to the KeyStone Admin API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
* @see TokenAsyncClient
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/Token_Operations.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public interface TokenClient {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a token and, if it is valid, return access information regarding the tenant (though not the service catalog)/
|
||||||
|
*
|
||||||
|
* @return the requested information
|
||||||
|
*/
|
||||||
|
Token get(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
|
||||||
|
*/
|
||||||
|
User getUserOfToken(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
|
||||||
|
*/
|
||||||
|
boolean isValid(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
|
||||||
|
*/
|
||||||
|
Set<Endpoint> listEndpointsForToken(String token);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.features;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
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.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.annotations.SkipEncoding;
|
||||||
|
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to User via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see UserClient
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/User_Operations.html"
|
||||||
|
* />
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Path("/v{" + Constants.PROPERTY_API_VERSION + "}")
|
||||||
|
@SkipEncoding({ '/', '=' })
|
||||||
|
public interface UserAsyncClient {
|
||||||
|
|
||||||
|
/** @see UserClient#list() */
|
||||||
|
@GET
|
||||||
|
@SelectJson("users")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/users")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<User>> list();
|
||||||
|
|
||||||
|
/** @see UserClient#get(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("user")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/users/{userId}")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<User> get(@PathParam("userId") String userId);
|
||||||
|
|
||||||
|
/** @see UserClient#getByName(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("user")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/users")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<User> getByName(@QueryParam("name") String userName);
|
||||||
|
|
||||||
|
/** @see UserClient#listRolesOfUser(String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("roles")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/users/{userId}/roles")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Role>> listRolesOfUser(@PathParam("userId") String userId);
|
||||||
|
|
||||||
|
/** @see UserClient#listRolesOfUserOnTenant(String, String) */
|
||||||
|
@GET
|
||||||
|
@SelectJson("roles")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/tenants/{tenantId}/users/{userId}/roles")
|
||||||
|
@RequestFilters(AuthenticateRequest.class)
|
||||||
|
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Set<Role>> listRolesOfUserOnTenant(@PathParam("userId") String userId, @PathParam("tenantId") String tenantId);
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.features;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to the KeyStone User API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
* @see UserAsyncClient
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.openstack.org/api/openstack-identity-service/2.0/content/User_Operations.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public interface UserClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the list of users
|
||||||
|
* <p/>
|
||||||
|
* NOTE: this method is not in API documentation for keystone, but does work
|
||||||
|
*
|
||||||
|
* @return the list of users
|
||||||
|
*/
|
||||||
|
Set<User> list();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a user, by user ID
|
||||||
|
*
|
||||||
|
* @return the information about the user
|
||||||
|
*/
|
||||||
|
User get(String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve information about a user, by user name
|
||||||
|
* <p/>
|
||||||
|
* NOTE: currently not working in openstack ( https://bugs.launchpad.net/keystone/+bug/956687 )
|
||||||
|
*
|
||||||
|
* @return the information about the user
|
||||||
|
*/
|
||||||
|
User getByName(String userName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of global roles associated with a specific user (excludes tenant roles).
|
||||||
|
* <p/>
|
||||||
|
* NOTE: Broken in openstack ( https://bugs.launchpad.net/keystone/+bug/933565 )
|
||||||
|
*
|
||||||
|
* @return the set of Roles granted to the user
|
||||||
|
*/
|
||||||
|
Set<Role> listRolesOfUser(String userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List the roles a user has been granted on a specific tenant
|
||||||
|
*
|
||||||
|
* @return the set of roles
|
||||||
|
*/
|
||||||
|
Set<Role> listRolesOfUserOnTenant(String userId, String tenantId);
|
||||||
|
|
||||||
|
}
|
|
@ -21,17 +21,17 @@ package org.jclouds.openstack.keystone.v2_0.functions;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.AuthenticationClient;
|
import org.jclouds.openstack.keystone.v2_0.AuthenticationClient;
|
||||||
|
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.Access;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials;
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.openstack.keystone.v2_0.functions.internal.BaseAuthenticator;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
|
|
||||||
|
@CredentialType(CredentialTypes.API_ACCESS_KEY_CREDENTIALS)
|
||||||
@Singleton
|
@Singleton
|
||||||
public class AuthenticateApiAccessKeyCredentials implements Function<Credentials, Access> {
|
public class AuthenticateApiAccessKeyCredentials extends BaseAuthenticator<ApiAccessKeyCredentials> {
|
||||||
private final AuthenticationClient client;
|
protected final AuthenticationClient client;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AuthenticateApiAccessKeyCredentials(AuthenticationClient client) {
|
public AuthenticateApiAccessKeyCredentials(AuthenticationClient client) {
|
||||||
|
@ -39,25 +39,18 @@ public class AuthenticateApiAccessKeyCredentials implements Function<Credentials
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Access apply(Credentials input) {
|
protected Access authenticateWithTenantNameOrNull(String tenantId, ApiAccessKeyCredentials apiAccessKeyCredentials) {
|
||||||
if (input.identity.indexOf(':') == -1) {
|
return client.authenticateWithTenantNameAndCredentials(tenantId, apiAccessKeyCredentials);
|
||||||
throw new AuthorizationException(String.format("Identity %s does not match format tenantName:accessKey",
|
}
|
||||||
input.identity), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
String tenantId = input.identity.substring(0, input.identity.indexOf(':'));
|
@Override
|
||||||
String usernameOrAccessKey = input.identity.substring(input.identity.indexOf(':') + 1);
|
protected Access authenticateWithTenantId(String tenantId, ApiAccessKeyCredentials apiAccessKeyCredentials) {
|
||||||
String passwordOrSecretKey = input.credential;
|
return client.authenticateWithTenantIdAndCredentials(tenantId, apiAccessKeyCredentials);
|
||||||
|
}
|
||||||
|
|
||||||
ApiAccessKeyCredentials apiAccessKeyCredentials = ApiAccessKeyCredentials.createWithAccessKeyAndSecretKey(
|
@Override
|
||||||
usernameOrAccessKey, passwordOrSecretKey);
|
public ApiAccessKeyCredentials createCredentials(String identity, String credential) {
|
||||||
Access access;
|
return ApiAccessKeyCredentials.createWithAccessKeyAndSecretKey(identity, credential);
|
||||||
if (tenantId.matches("^[0-9]+$")) {
|
|
||||||
access = client.authenticateWithTenantIdAndCredentials(tenantId, apiAccessKeyCredentials);
|
|
||||||
} else {
|
|
||||||
access = client.authenticateWithTenantNameAndCredentials(tenantId, apiAccessKeyCredentials);
|
|
||||||
}
|
|
||||||
return access;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,17 +19,19 @@
|
||||||
package org.jclouds.openstack.keystone.v2_0.functions;
|
package org.jclouds.openstack.keystone.v2_0.functions;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.AuthenticationClient;
|
import org.jclouds.openstack.keystone.v2_0.AuthenticationClient;
|
||||||
|
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.Access;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
|
import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.openstack.keystone.v2_0.functions.internal.BaseAuthenticator;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
@CredentialType(CredentialTypes.PASSWORD_CREDENTIALS)
|
||||||
|
@Singleton
|
||||||
public class AuthenticatePasswordCredentials implements Function<Credentials, Access> {
|
public class AuthenticatePasswordCredentials extends BaseAuthenticator<PasswordCredentials> {
|
||||||
private final AuthenticationClient client;
|
protected final AuthenticationClient client;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AuthenticatePasswordCredentials(AuthenticationClient client) {
|
public AuthenticatePasswordCredentials(AuthenticationClient client) {
|
||||||
|
@ -37,25 +39,18 @@ public class AuthenticatePasswordCredentials implements Function<Credentials, Ac
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Access apply(Credentials input) {
|
protected Access authenticateWithTenantNameOrNull(String tenantId, PasswordCredentials apiAccessKeyCredentials) {
|
||||||
if (input.identity.indexOf(':') == -1) {
|
return client.authenticateWithTenantNameAndCredentials(tenantId, apiAccessKeyCredentials);
|
||||||
throw new AuthorizationException(String.format("Identity %s does not match format tenantId:username",
|
}
|
||||||
input.identity), null);
|
|
||||||
}
|
|
||||||
|
|
||||||
String tenantId = input.identity.substring(0, input.identity.indexOf(':'));
|
@Override
|
||||||
String usernameOrAccessKey = input.identity.substring(input.identity.indexOf(':') + 1);
|
protected Access authenticateWithTenantId(String tenantId, PasswordCredentials apiAccessKeyCredentials) {
|
||||||
String passwordOrSecretKey = input.credential;
|
return client.authenticateWithTenantIdAndCredentials(tenantId, apiAccessKeyCredentials);
|
||||||
|
}
|
||||||
|
|
||||||
PasswordCredentials passwordCredentials = PasswordCredentials.createWithUsernameAndPassword(usernameOrAccessKey,
|
@Override
|
||||||
passwordOrSecretKey);
|
public PasswordCredentials createCredentials(String identity, String credential) {
|
||||||
Access access;
|
return PasswordCredentials.createWithUsernameAndPassword(identity, credential);
|
||||||
if (tenantId.matches("^[0-9]+$")) {
|
|
||||||
access = client.authenticateWithTenantIdAndCredentials(tenantId, passwordCredentials);
|
|
||||||
} else {
|
|
||||||
access = client.authenticateWithTenantNameAndCredentials(tenantId, passwordCredentials);
|
|
||||||
}
|
|
||||||
return access;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,7 +23,7 @@ import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.inject.ImplementedBy;
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
@ImplementedBy(ReturnRegion.class)
|
@ImplementedBy(ReturnRegionOrProvider.class)
|
||||||
public interface EndpointToRegion extends Function<Endpoint, String> {
|
public interface EndpointToRegion extends Function<Endpoint, String> {
|
||||||
|
|
||||||
}
|
}
|
|
@ -20,15 +20,23 @@ package org.jclouds.openstack.keystone.v2_0.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ReturnRegion implements EndpointToRegion {
|
public class ReturnRegionOrProvider implements EndpointToRegion {
|
||||||
|
private String provider;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ReturnRegionOrProvider(@Provider String provider) {
|
||||||
|
this.provider = checkNotNull(provider, "provider");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(Endpoint input) {
|
public String apply(Endpoint input) {
|
||||||
return checkNotNull(input.getRegion(), "no region for endpoint %s", input);
|
return input.getRegion() != null ? input.getRegion() : provider;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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 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;
|
||||||
|
|
||||||
|
public abstract class BaseAuthenticator<C> implements Function<Credentials, Access> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Access apply(Credentials input) {
|
||||||
|
String tenantId = null;
|
||||||
|
String usernameOrAccessKey = input.identity;
|
||||||
|
if (input.identity.indexOf(':') == -1) {
|
||||||
|
logger.debug("Identity %s does not match format tenantName:accessKey", input.identity);
|
||||||
|
} else {
|
||||||
|
tenantId = input.identity.substring(0, input.identity.indexOf(':'));
|
||||||
|
usernameOrAccessKey = input.identity.substring(input.identity.indexOf(':') + 1);
|
||||||
|
}
|
||||||
|
String passwordOrSecretKey = input.credential;
|
||||||
|
|
||||||
|
C creds = createCredentials(usernameOrAccessKey, passwordOrSecretKey);
|
||||||
|
Access access;
|
||||||
|
if (tenantId != null && tenantId.matches("^[0-9]+$")) {
|
||||||
|
access = authenticateWithTenantId(tenantId, creds);
|
||||||
|
} else {
|
||||||
|
access = authenticateWithTenantNameOrNull(tenantId, creds);
|
||||||
|
}
|
||||||
|
return access;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract C createCredentials(String identity, String credential);
|
||||||
|
|
||||||
|
protected abstract Access authenticateWithTenantId(String tenantId, C apiAccessKeyCredentials);
|
||||||
|
|
||||||
|
protected abstract Access authenticateWithTenantNameOrNull(String tenantId, C apiAccessKeyCredentials);
|
||||||
|
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ import com.google.common.collect.Maps;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class LocationIdToURIFromAccessForTypeAndVersionSupplier implements Supplier<Map<String, Supplier<URI>>> {
|
public class LocationIdToURIFromAccessForTypeAndVersion implements Supplier<Map<String, Supplier<URI>>> {
|
||||||
protected final Supplier<Access> access;
|
protected final Supplier<Access> access;
|
||||||
protected final EndpointToSupplierURI endpointToSupplierURI;
|
protected final EndpointToSupplierURI endpointToSupplierURI;
|
||||||
protected final Function<Endpoint, String> endpointToLocationId;
|
protected final Function<Endpoint, String> endpointToLocationId;
|
||||||
|
@ -46,7 +46,7 @@ public class LocationIdToURIFromAccessForTypeAndVersionSupplier implements Suppl
|
||||||
protected final String apiVersion;
|
protected final String apiVersion;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public LocationIdToURIFromAccessForTypeAndVersionSupplier(Supplier<Access> access,
|
public LocationIdToURIFromAccessForTypeAndVersion(Supplier<Access> access,
|
||||||
EndpointToSupplierURI endpointToSupplierURI, Function<Endpoint, String> endpointToLocationId,
|
EndpointToSupplierURI endpointToSupplierURI, Function<Endpoint, String> endpointToLocationId,
|
||||||
@Assisted("apiType") String apiType, @Assisted("apiVersion") String apiVersion) {
|
@Assisted("apiType") String apiType, @Assisted("apiVersion") String apiVersion) {
|
||||||
this.access = access;
|
this.access = access;
|
||||||
|
@ -70,8 +70,8 @@ public class LocationIdToURIFromAccessForTypeAndVersionSupplier implements Suppl
|
||||||
|
|
||||||
});
|
});
|
||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
throw new NoSuchElementException(String.format("apiType %s not found in catalog %s", apiType,
|
throw new NoSuchElementException(String.format("apiType %s not found in catalog %s", apiType, accessResponse
|
||||||
accessResponse.getServiceCatalog()));
|
.getServiceCatalog()));
|
||||||
}
|
}
|
||||||
Map<String, Endpoint> locationIdToEndpoint = Maps.uniqueIndex(Iterables.filter(service.getEndpoints(),
|
Map<String, Endpoint> locationIdToEndpoint = Maps.uniqueIndex(Iterables.filter(service.getEndpoints(),
|
||||||
new Predicate<Endpoint>() {
|
new Predicate<Endpoint>() {
|
|
@ -21,6 +21,7 @@ package org.jclouds.openstack.keystone.v2_0.suppliers;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
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.EndpointToRegion;
|
||||||
import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierAdminURI;
|
import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierAdminURI;
|
||||||
|
@ -29,12 +30,12 @@ import com.google.common.base.Supplier;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class RegionIdToAdminURIFromAccessForTypeAndVersionSupplier extends
|
public class RegionIdToAdminURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
|
||||||
LocationIdToURIFromAccessForTypeAndVersionSupplier implements RegionIdToAdminURISupplier {
|
RegionIdToAdminURISupplier {
|
||||||
@Inject
|
@Inject
|
||||||
public RegionIdToAdminURIFromAccessForTypeAndVersionSupplier(Supplier<Access> access,
|
public RegionIdToAdminURIFromAccessForTypeAndVersion(Supplier<Access> access,
|
||||||
EndpointToSupplierAdminURI endpointToSupplierURI, EndpointToRegion endpointToRegion,
|
EndpointToSupplierAdminURI endpointToSupplierURI, EndpointToRegion endpointToRegion,
|
||||||
@Assisted("apiType") String apiType, @Assisted("apiVersion") String apiVersion) {
|
@Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
|
||||||
super(access, endpointToSupplierURI, endpointToRegion, apiType, apiVersion);
|
super(access, endpointToSupplierURI, endpointToRegion, apiType, apiVersion);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package org.jclouds.openstack.keystone.v2_0.suppliers;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.ImplementedBy;
|
import com.google.inject.ImplementedBy;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
@ -10,7 +12,7 @@ import com.google.inject.assistedinject.Assisted;
|
||||||
/**
|
/**
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
*/
|
*/
|
||||||
@ImplementedBy(RegionIdToAdminURIFromAccessForTypeAndVersionSupplier.class)
|
@ImplementedBy(RegionIdToAdminURIFromAccessForTypeAndVersion.class)
|
||||||
public interface RegionIdToAdminURISupplier extends Supplier<Map<String, Supplier<URI>>> {
|
public interface RegionIdToAdminURISupplier extends Supplier<Map<String, Supplier<URI>>> {
|
||||||
static interface Factory {
|
static interface Factory {
|
||||||
/**
|
/**
|
||||||
|
@ -19,10 +21,10 @@ public interface RegionIdToAdminURISupplier extends Supplier<Map<String, Supplie
|
||||||
* type of the api, according to the provider. ex. {@code compute} {@code
|
* type of the api, according to the provider. ex. {@code compute} {@code
|
||||||
* object-store}
|
* object-store}
|
||||||
* @param apiVersion
|
* @param apiVersion
|
||||||
* version of the api
|
* version of the api, or null
|
||||||
* @return regions mapped to default uri
|
* @return regions mapped to default uri
|
||||||
*/
|
*/
|
||||||
RegionIdToAdminURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType,
|
RegionIdToAdminURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType,
|
||||||
@Assisted("apiVersion") String apiVersion);
|
@Nullable @Assisted("apiVersion") String apiVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.openstack.keystone.v2_0.suppliers;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.location.suppliers.RegionIdToURISupplier;
|
import org.jclouds.location.suppliers.RegionIdToURISupplier;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
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.EndpointToRegion;
|
||||||
|
@ -30,13 +31,13 @@ import com.google.common.base.Supplier;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class RegionIdToURIFromAccessForTypeAndVersionSupplier extends
|
public class RegionIdToURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
|
||||||
LocationIdToURIFromAccessForTypeAndVersionSupplier implements RegionIdToURISupplier {
|
RegionIdToURISupplier {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RegionIdToURIFromAccessForTypeAndVersionSupplier(Supplier<Access> access,
|
public RegionIdToURIFromAccessForTypeAndVersion(Supplier<Access> access,
|
||||||
EndpointToSupplierURI endpointToSupplierURI, EndpointToRegion endpointToRegion,
|
EndpointToSupplierURI endpointToSupplierURI, EndpointToRegion endpointToRegion,
|
||||||
@Assisted("apiType") String apiType, @Assisted("apiVersion") String apiVersion) {
|
@Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
|
||||||
super(access, endpointToSupplierURI, endpointToRegion, apiType, apiVersion);
|
super(access, endpointToSupplierURI, endpointToRegion, apiType, apiVersion);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.openstack.keystone.v2_0.suppliers;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.location.suppliers.ZoneIdToURISupplier;
|
import org.jclouds.location.suppliers.ZoneIdToURISupplier;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
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.EndpointToRegion;
|
||||||
|
@ -30,16 +31,16 @@ import com.google.common.base.Supplier;
|
||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ZoneIdToURIFromAccessForTypeAndVersionSupplier extends LocationIdToURIFromAccessForTypeAndVersionSupplier
|
public class ZoneIdToURIFromAccessForTypeAndVersion extends LocationIdToURIFromAccessForTypeAndVersion implements
|
||||||
implements ZoneIdToURISupplier {
|
ZoneIdToURISupplier {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ZoneIdToURIFromAccessForTypeAndVersionSupplier(
|
public ZoneIdToURIFromAccessForTypeAndVersion(
|
||||||
Supplier<Access> access,
|
Supplier<Access> access,
|
||||||
// NOTE that in some services, the region is in fact the zone. temporarily, we need
|
// NOTE that in some services, the region is in fact the zone. temporarily, we need
|
||||||
// to use the region field, in this case.
|
// to use the region field, in this case.
|
||||||
EndpointToSupplierURI endpointToSupplierURI, EndpointToRegion endpointToZone,
|
EndpointToSupplierURI endpointToSupplierURI, EndpointToRegion endpointToZone,
|
||||||
@Assisted("apiType") String apiType, @Assisted("apiVersion") String apiVersion) {
|
@Assisted("apiType") String apiType, @Nullable @Assisted("apiVersion") String apiVersion) {
|
||||||
super(access, endpointToSupplierURI, endpointToZone, apiType, apiVersion);
|
super(access, endpointToSupplierURI, endpointToZone, apiType, apiVersion);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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 static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestClientExpectTest;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceApiMetadataTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(testName = "KeystoneClientExpectTest")
|
||||||
|
public class KeystoneClientExpectTest extends BaseKeystoneRestClientExpectTest<KeystoneClient> {
|
||||||
|
|
||||||
|
public void testGetApiMetaData() {
|
||||||
|
KeystoneClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
HttpRequest.builder().method("GET").endpoint(URI.create(endpoint + "/v2.0/")).
|
||||||
|
headers(ImmutableMultimap.of("Accept", APPLICATION_JSON)).build(),
|
||||||
|
HttpResponse.builder().statusCode(200).
|
||||||
|
payload(payloadFromResourceWithContentType("/raxVersion.json", APPLICATION_JSON)).build());
|
||||||
|
ApiMetadata metadata = client.getApiMetadata();
|
||||||
|
|
||||||
|
assertEquals(metadata, new ParseRackspaceApiMetadataTest().expected());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetApiMetaDataFailNotFound() {
|
||||||
|
KeystoneClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/").headers(ImmutableMultimap.of("Accept", APPLICATION_JSON)).build(),
|
||||||
|
standardResponseBuilder(404).build());
|
||||||
|
assertNull(client.getApiMetadata());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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 static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneClientLiveTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests KeystoneClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "KeystoneClientLiveTest")
|
||||||
|
public class KeystoneClientLiveTest extends BaseKeystoneClientLiveTest {
|
||||||
|
|
||||||
|
public void testGetApiMetaData() {
|
||||||
|
ApiMetadata result = keystoneContext.getApi().getApiMetadata();
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNotNull(result.getId());
|
||||||
|
assertNotNull(result.getStatus());
|
||||||
|
assertNotNull(result.getUpdated());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@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(""));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,381 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 1.1 (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-1.1
|
|
||||||
*
|
|
||||||
* 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.features;
|
|
||||||
|
|
||||||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import static org.testng.Assert.assertFalse;
|
|
||||||
import static org.testng.Assert.assertNotNull;
|
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.jclouds.date.DateService;
|
|
||||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
|
||||||
import org.jclouds.http.HttpResponseException;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.KeystoneClient;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.MediaType;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
|
||||||
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.internal.BaseKeystoneRestClientExpectTest;
|
|
||||||
import org.jclouds.openstack.v2_0.domain.Link;
|
|
||||||
import org.jclouds.rest.AuthorizationException;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests parsing and Guice wiring of UserClient
|
|
||||||
*
|
|
||||||
* @author Adam Lowe
|
|
||||||
*/
|
|
||||||
@Test(testName = "AdminClientExpectTest")
|
|
||||||
public class AdminClientExpectTest extends BaseKeystoneRestClientExpectTest<KeystoneClient> {
|
|
||||||
private DateService dateService = new SimpleDateFormatDateService();
|
|
||||||
|
|
||||||
public AdminClientExpectTest() {
|
|
||||||
endpoint = "https://csnode.jclouds.org:35357";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetApiMetaData() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/").
|
|
||||||
headers(ImmutableMultimap.of("Accept", APPLICATION_JSON)).build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/api_metadata.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
ApiMetadata metadata = client.getApiMetadata();
|
|
||||||
assertNotNull(metadata);
|
|
||||||
assertEquals(metadata.getId(), "v2.0");
|
|
||||||
|
|
||||||
ApiMetadata expected = ApiMetadata.builder().id("v2.0")
|
|
||||||
.links(ImmutableSet.of(Link.builder().relation(Link.Relation.SELF).href(URI.create("http://172.16.89.140:5000/v2.0/")).build(),
|
|
||||||
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("text/html").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/content/")).build(),
|
|
||||||
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("application/pdf").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf")).build()
|
|
||||||
))
|
|
||||||
.status("beta")
|
|
||||||
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-11-19T00:00:00Z"))
|
|
||||||
.mediaTypes(ImmutableSet.of(
|
|
||||||
MediaType.builder().base("application/json").type("application/vnd.openstack.identity-v2.0+json").build(),
|
|
||||||
MediaType.builder().base("application/xml").type("application/vnd.openstack.identity-v2.0+xml").build()
|
|
||||||
))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertEquals(metadata, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetApiMetaDataFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/").headers(ImmutableMultimap.of("Accept", APPLICATION_JSON)).build(),
|
|
||||||
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertNull(client.getApiMetadata());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListTenants() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tenants").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
Set<Tenant> tenants = client.listTenants();
|
|
||||||
assertNotNull(tenants);
|
|
||||||
assertFalse(tenants.isEmpty());
|
|
||||||
|
|
||||||
Set<Tenant> expected = ImmutableSet.of(
|
|
||||||
Tenant.builder().name("demo").id("05d1dc7af71646deba64cfc17b81bec0").build(),
|
|
||||||
Tenant.builder().name("admin").id("7aa2e17ec29f44d193c48feaba0852cc").build()
|
|
||||||
);
|
|
||||||
|
|
||||||
assertEquals(tenants, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListTenantsFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tenants").build(),
|
|
||||||
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertTrue(client.listTenants().isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetTenant() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tenants/013ba41150a14830bec85ffe93353bcc").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/tenant_details.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
Tenant tenant = client.getTenant("013ba41150a14830bec85ffe93353bcc");
|
|
||||||
assertNotNull(tenant);
|
|
||||||
assertEquals(tenant, Tenant.builder().id("013ba41150a14830bec85ffe93353bcc").name("admin").build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = AuthorizationException.class)
|
|
||||||
public void testListTenantsFailNotAuthorized() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tenants/013ba41150a14830bec85ffe93353bcc").build(),
|
|
||||||
standardResponseBuilder(401).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
client.getTenant("013ba41150a14830bec85ffe93353bcc");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetTenantByName() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tenants?name=admin").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/tenant_details.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
Tenant tenant = client.getTenantByName("admin");
|
|
||||||
assertNotNull(tenant);
|
|
||||||
assertEquals(tenant, Tenant.builder().id("013ba41150a14830bec85ffe93353bcc").name("admin").build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetTenantByNameFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tenants?name=admin").build(),
|
|
||||||
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertNull(client.getTenantByName("admin"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetToken() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/token_details.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
Token token = client.getToken("sometokenorother");
|
|
||||||
assertNotNull(token);
|
|
||||||
assertEquals(token,
|
|
||||||
Token.builder().id("167eccdc790946969ced473732e8109b").expires(dateService.iso8601SecondsDateParse("2012-04-28T12:42:50Z"))
|
|
||||||
.tenant(Tenant.builder().id("4cea93f5464b4f1c921fb3e0461d72b5").name("demo").build()).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetTokenFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
|
||||||
standardResponseBuilder(404).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertNull(client.getToken("sometokenorother"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = HttpResponseException.class)
|
|
||||||
public void testGetTokenFail500() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
|
||||||
standardResponseBuilder(500).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
client.getToken("sometokenorother");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetUserOfToken() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/token_details.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
User user = client.getUserOfToken("sometokenorother");
|
|
||||||
assertNotNull(user);
|
|
||||||
assertEquals(user, User.builder().id("2b9b606181634ae9ac86fd95a8bc2cde").name("admin")
|
|
||||||
.roles(ImmutableSet.of(Role.builder().id("79cada5c02814b57a52e0eed4dd388cb").name("admin").build()))
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetUserOfTokenFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
|
||||||
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertNull(client.getUserOfToken("sometokenorother"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCheckTokenIsValid() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").method("HEAD")
|
|
||||||
.headers(ImmutableMultimap.of("X-Auth-Token", authToken)).build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/token_details.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertTrue(client.checkTokenIsValid("sometokenorother"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCheckTokenIsValidFailNotValid() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").method("HEAD")
|
|
||||||
.headers(ImmutableMultimap.of("X-Auth-Token", authToken)).build(),
|
|
||||||
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertFalse(client.checkTokenIsValid("sometokenorother"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetEndpointsForToken() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tokens/XXXXXX/endpoints").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_endpoints.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
Set<Endpoint> endpoints = client.getEndpointsForToken("XXXXXX");
|
|
||||||
|
|
||||||
assertEquals(endpoints, ImmutableSet.of(
|
|
||||||
Endpoint.builder().publicURL(URI.create("https://csnode.jclouds.org/v2.0/"))
|
|
||||||
.adminURL(URI.create("https://csnode.jclouds.org:35357/v2.0/"))
|
|
||||||
.region("region-a.geo-1").versionId("2.0").build()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetEndpointsForTokenFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/tokens/XXXXXX/endpoints").build(),
|
|
||||||
standardResponseBuilder(404).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertTrue(client.getEndpointsForToken("XXXXXX").isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListUsers() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_list.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
Set<User> users = client.listUsers();
|
|
||||||
assertNotNull(users);
|
|
||||||
assertFalse(users.isEmpty());
|
|
||||||
|
|
||||||
Set<User> expected = ImmutableSet.of(
|
|
||||||
User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
|
||||||
User.builder().name("glance").id("3f6c1c9ba993495ead7d2eb2192e284f").build(),
|
|
||||||
User.builder().name("demo").id("667b2e1420604df8b67cd8ea57d4ee64").build(),
|
|
||||||
User.builder().name("admin").id("2b9b606181634ae9ac86fd95a8bc2cde").build()
|
|
||||||
);
|
|
||||||
|
|
||||||
assertEquals(users, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = AuthorizationException.class)
|
|
||||||
public void testListUsersFailNotAuth() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users").build(),
|
|
||||||
standardResponseBuilder(401).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
client.listUsers();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetUser() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users/e021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_details.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
User user = client.getUser("e021dfd758eb44a89f1c57c8ef3be8e2");
|
|
||||||
assertNotNull(user);
|
|
||||||
assertEquals(user, User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetUserFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users/f021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
|
||||||
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertNull(client.getUser("f021dfd758eb44a89f1c57c8ef3be8e2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetUserByName() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users?name=nova").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_details.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
User user = client.getUserByName("nova");
|
|
||||||
assertNotNull(user);
|
|
||||||
assertEquals(user, User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetUserByNameFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users?name=fred").build(),
|
|
||||||
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertNull(client.getUserByName("fred"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListRolesOfUser() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_role_list.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
Set<Role> roles = client.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f");
|
|
||||||
assertNotNull(roles);
|
|
||||||
assertFalse(roles.isEmpty());
|
|
||||||
assertEquals(roles, ImmutableSet.of(
|
|
||||||
Role.builder().id("79cada5c02814b57a52e0eed4dd388cb").name("admin").build()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListRolesOfUserFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users/4f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
|
||||||
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertTrue(client.listRolesOfUser("4f6c1c9ba993495ead7d2eb2192e284f").isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = HttpResponseException.class)
|
|
||||||
public void testListRolesOfUserFailNotImplemented() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users/5f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
|
||||||
standardResponseBuilder(501).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertTrue(client.listRolesOfUser("5f6c1c9ba993495ead7d2eb2192e284f").isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListRolesOfUserInTenant() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
|
||||||
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_tenant_role_list.json", APPLICATION_JSON)).build())
|
|
||||||
.getAdminClientForRegion("region-a.geo-1");
|
|
||||||
Set<Role> roles = client.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f");
|
|
||||||
assertNotNull(roles);
|
|
||||||
assertFalse(roles.isEmpty());
|
|
||||||
assertEquals(roles, ImmutableSet.of(
|
|
||||||
Role.builder().id("31c451195aac49b386039341e2c92a16").name("KeystoneServiceAdmin").build(),
|
|
||||||
Role.builder().id("79cada5c02814b57a52e0eed4dd388cb").name("admin").build(),
|
|
||||||
Role.builder().id("6ea17ddd37a6447794cb0e164d4db894").name("KeystoneAdmin").build()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListRolesOfUserInTenantFailNotFound() {
|
|
||||||
AdminClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
standardRequestBuilder(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
|
||||||
standardResponseBuilder(404).build()).getAdminClientForRegion("region-a.geo-1");
|
|
||||||
assertTrue(client.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f").isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,192 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 1.1 (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-1.1
|
|
||||||
*
|
|
||||||
* 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.features;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import static org.testng.Assert.assertFalse;
|
|
||||||
import static org.testng.Assert.assertNotNull;
|
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
import static org.testng.AssertJUnit.assertTrue;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
|
||||||
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.BaseKeystoneClientLiveTest;
|
|
||||||
import org.testng.annotations.BeforeMethod;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests AdminClient
|
|
||||||
*
|
|
||||||
* @author Adam Lowe
|
|
||||||
*/
|
|
||||||
@Test(groups = "live", testName = "AdminClientLiveTest", singleThreaded = true)
|
|
||||||
public class AdminClientLiveTest extends BaseKeystoneClientLiveTest {
|
|
||||||
|
|
||||||
protected String token;
|
|
||||||
|
|
||||||
// Get the token currently in use (there's currently no listTokens())
|
|
||||||
@BeforeMethod
|
|
||||||
public void grabToken() {
|
|
||||||
AuthenticateRequest ar = keystoneContext.getUtils().getInjector().getInstance(AuthenticateRequest.class);
|
|
||||||
HttpRequest test = ar.filter(HttpRequest.builder().method("GET").endpoint(URI.create(endpoint)).build());
|
|
||||||
token = Iterables.getOnlyElement(test.getHeaders().get("X-Auth-Token"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetApiMetaData() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
ApiMetadata result = keystoneContext.getApi().getAdminClientForRegion(regionId).getApiMetadata();
|
|
||||||
assertNotNull(result);
|
|
||||||
assertNotNull(result.getId());
|
|
||||||
assertNotNull(result.getStatus());
|
|
||||||
assertNotNull(result.getUpdated());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testTenants() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
|
||||||
Set<Tenant> result = client.listTenants();
|
|
||||||
assertNotNull(result);
|
|
||||||
assertFalse(result.isEmpty());
|
|
||||||
|
|
||||||
for (Tenant tenant : result) {
|
|
||||||
assertNotNull(tenant.getId());
|
|
||||||
|
|
||||||
Tenant aTenant = client.getTenant(tenant.getId());
|
|
||||||
assertEquals(aTenant, tenant);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testToken() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
|
||||||
assertTrue(client.checkTokenIsValid(token));
|
|
||||||
Token result = client.getToken(token);
|
|
||||||
assertNotNull(result);
|
|
||||||
assertEquals(result.getId(), token);
|
|
||||||
assertNotNull(result.getTenant());
|
|
||||||
|
|
||||||
User user = client.getUserOfToken(token);
|
|
||||||
assertNotNull(user);
|
|
||||||
assertNotNull(user.getId());
|
|
||||||
assertNotNull(user.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testInvalidToken() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
|
||||||
assertFalse(client.checkTokenIsValid("thisisnotarealtoken!"));
|
|
||||||
assertNull(client.getToken("thisisnotarealtoken!"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO this threw 501 not implemented
|
|
||||||
@Test(enabled = false)
|
|
||||||
public void testTokenEndpoints() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
|
||||||
Set<Endpoint> endpoints = client.getEndpointsForToken(token);
|
|
||||||
assertNotNull(endpoints);
|
|
||||||
assertFalse(endpoints.isEmpty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO this threw 501 not implemented
|
|
||||||
@Test(enabled = false)
|
|
||||||
public void testInvalidTokenEndpoints() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
|
||||||
assertTrue(client.getEndpointsForToken("thisisnotarealtoken!").isEmpty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testUsers() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
|
||||||
Set<User> users = client.listUsers();
|
|
||||||
assertNotNull(users);
|
|
||||||
assertFalse(users.isEmpty());
|
|
||||||
for (User user : users) {
|
|
||||||
User aUser = client.getUser(user.getId());
|
|
||||||
assertEquals(aUser, user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods = {"testUsers", "testTenants"})
|
|
||||||
public void testUserRolesOnTenant() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
|
||||||
Set<User> users = client.listUsers();
|
|
||||||
Set<Tenant> tenants = client.listTenants();
|
|
||||||
|
|
||||||
for (User user : users) {
|
|
||||||
for (Tenant tenant : tenants) {
|
|
||||||
Set<Role> roles = client.listRolesOfUserOnTenant(user.getId(), tenant.getId());
|
|
||||||
for (Role role : roles) {
|
|
||||||
assertNotNull(role.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO this functionality is currently broken in openstack
|
|
||||||
@Test(enabled = false, dependsOnMethods = "testUsers")
|
|
||||||
public void testListRolesOfUser() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
|
||||||
for (User user : client.listUsers()) {
|
|
||||||
Set<Role> roles = client.listRolesOfUser(user.getId());
|
|
||||||
for (Role role : roles) {
|
|
||||||
assertNotNull(role.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO this functionality is currently broken in openstack (possibly deprecated?)
|
|
||||||
@Test(enabled=false, dependsOnMethods = {"testUsers", "testTenants"})
|
|
||||||
public void testUsersAndTenantsByName() {
|
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
AdminClient client = keystoneContext.getApi().getAdminClientForRegion(regionId);
|
|
||||||
for (User user : client.listUsers()) {
|
|
||||||
User aUser = client.getUserByName(user.getName());
|
|
||||||
assertEquals(aUser, user);
|
|
||||||
}
|
|
||||||
for (Tenant tenant : client.listTenants()) {
|
|
||||||
Tenant aTenant = client.getTenantByName(tenant.getName());
|
|
||||||
assertEquals(aTenant, tenant);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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.features;
|
||||||
|
|
||||||
|
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.KeystoneClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestClientExpectTest;
|
||||||
|
import org.jclouds.rest.AuthorizationException;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests parsing and Guice wiring of TenantClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(testName = "TenantClientExpectTest")
|
||||||
|
public class TenantClientExpectTest extends BaseKeystoneRestClientExpectTest<KeystoneClient> {
|
||||||
|
|
||||||
|
public void testListTenants() {
|
||||||
|
TenantClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants").build(),
|
||||||
|
standardResponseBuilder(200).payload(
|
||||||
|
payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
|
||||||
|
.getTenantClient();
|
||||||
|
Set<Tenant> tenants = client.list();
|
||||||
|
assertNotNull(tenants);
|
||||||
|
assertFalse(tenants.isEmpty());
|
||||||
|
|
||||||
|
Set<Tenant> expected = ImmutableSet.of(Tenant.builder().name("demo").id("05d1dc7af71646deba64cfc17b81bec0")
|
||||||
|
.build(), Tenant.builder().name("admin").id("7aa2e17ec29f44d193c48feaba0852cc").build());
|
||||||
|
|
||||||
|
assertEquals(tenants, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListTenantsFailNotFound() {
|
||||||
|
TenantClient client = requestsSendResponses(keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants").build(), standardResponseBuilder(404).build())
|
||||||
|
.getTenantClient();
|
||||||
|
assertTrue(client.list().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetTenant() {
|
||||||
|
TenantClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants/013ba41150a14830bec85ffe93353bcc").build(),
|
||||||
|
standardResponseBuilder(200).payload(
|
||||||
|
payloadFromResourceWithContentType("/tenant_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getTenantClient();
|
||||||
|
Tenant tenant = client.get("013ba41150a14830bec85ffe93353bcc");
|
||||||
|
assertNotNull(tenant);
|
||||||
|
assertEquals(tenant, Tenant.builder().id("013ba41150a14830bec85ffe93353bcc").name("admin").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = AuthorizationException.class)
|
||||||
|
public void testListTenantsFailNotAuthorized() {
|
||||||
|
TenantClient client = requestsSendResponses(keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants/013ba41150a14830bec85ffe93353bcc").build(),
|
||||||
|
standardResponseBuilder(401).build()).getTenantClient();
|
||||||
|
client.get("013ba41150a14830bec85ffe93353bcc");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetTenantByName() {
|
||||||
|
TenantClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword,
|
||||||
|
responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants?name=admin").build(),
|
||||||
|
standardResponseBuilder(200).payload(
|
||||||
|
payloadFromResourceWithContentType("/tenant_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getTenantClient();
|
||||||
|
Tenant tenant = client.getByName("admin");
|
||||||
|
assertNotNull(tenant);
|
||||||
|
assertEquals(tenant, Tenant.builder().id("013ba41150a14830bec85ffe93353bcc").name("admin").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetTenantByNameFailNotFound() {
|
||||||
|
TenantClient client = requestsSendResponses(keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tenants?name=admin").build(),
|
||||||
|
standardResponseBuilder(404).build()).getTenantClient();
|
||||||
|
assertNull(client.getByName("admin"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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.features;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneClientLiveTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests TenantClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "TenantClientLiveTest")
|
||||||
|
public class TenantClientLiveTest extends BaseKeystoneClientLiveTest {
|
||||||
|
|
||||||
|
public void testTenants() {
|
||||||
|
TenantClient client = keystoneContext.getApi().getTenantClient();
|
||||||
|
Set<Tenant> result = client.list();
|
||||||
|
assertNotNull(result);
|
||||||
|
assertFalse(result.isEmpty());
|
||||||
|
|
||||||
|
for (Tenant tenant : result) {
|
||||||
|
assertNotNull(tenant.getId());
|
||||||
|
|
||||||
|
Tenant aTenant = client.get(tenant.getId());
|
||||||
|
assertNotNull(aTenant, "get returned null for tenant: " + tenant);
|
||||||
|
|
||||||
|
assertEquals(aTenant, tenant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTenantsByName() {
|
||||||
|
|
||||||
|
TenantClient client = keystoneContext.getApi().getTenantClient();
|
||||||
|
|
||||||
|
for (Tenant tenant : client.list()) {
|
||||||
|
Tenant aTenant = client.getByName(tenant.getName());
|
||||||
|
assertNotNull(aTenant, "get returned null for tenant: " + tenant);
|
||||||
|
|
||||||
|
assertEquals(aTenant, tenant);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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.features;
|
||||||
|
|
||||||
|
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.date.DateService;
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.KeystoneClient;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Endpoint;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
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.internal.BaseKeystoneRestClientExpectTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests parsing and Guice wiring of TokenClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(testName = "TokenClientExpectTest")
|
||||||
|
public class TokenClientExpectTest extends BaseKeystoneRestClientExpectTest<KeystoneClient> {
|
||||||
|
private DateService dateService = new SimpleDateFormatDateService();
|
||||||
|
|
||||||
|
public void testGetToken() {
|
||||||
|
TokenClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/token_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getTokenClient();
|
||||||
|
Token token = client.get("sometokenorother");
|
||||||
|
assertNotNull(token);
|
||||||
|
assertEquals(token,
|
||||||
|
Token.builder().id("167eccdc790946969ced473732e8109b").expires(dateService.iso8601SecondsDateParse("2012-04-28T12:42:50Z"))
|
||||||
|
.tenant(Tenant.builder().id("4cea93f5464b4f1c921fb3e0461d72b5").name("demo").build()).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetTokenFailNotFound() {
|
||||||
|
TokenClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(404).build())
|
||||||
|
.getTokenClient();
|
||||||
|
assertNull(client.get("sometokenorother"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = HttpResponseException.class)
|
||||||
|
public void testGetTokenFail500() {
|
||||||
|
TokenClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(500).build()).getTokenClient();
|
||||||
|
client.get("sometokenorother");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserOfToken() {
|
||||||
|
TokenClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/token_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getTokenClient();
|
||||||
|
User user = client.getUserOfToken("sometokenorother");
|
||||||
|
assertNotNull(user);
|
||||||
|
assertEquals(user, User.builder().id("2b9b606181634ae9ac86fd95a8bc2cde").name("admin")
|
||||||
|
.roles(ImmutableSet.of(Role.builder().id("79cada5c02814b57a52e0eed4dd388cb").name("admin").build()))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserOfTokenFailNotFound() {
|
||||||
|
TokenClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").build(),
|
||||||
|
standardResponseBuilder(404).build()).getTokenClient();
|
||||||
|
assertNull(client.getUserOfToken("sometokenorother"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCheckTokenIsValid() {
|
||||||
|
TokenClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").method("HEAD")
|
||||||
|
.headers(ImmutableMultimap.of("X-Auth-Token", authToken)).build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/token_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getTokenClient();
|
||||||
|
assertTrue(client.isValid("sometokenorother"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCheckTokenIsValidFailNotValid() {
|
||||||
|
TokenClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/sometokenorother").method("HEAD")
|
||||||
|
.headers(ImmutableMultimap.of("X-Auth-Token", authToken)).build(),
|
||||||
|
standardResponseBuilder(404).build()).getTokenClient();
|
||||||
|
assertFalse(client.isValid("sometokenorother"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEndpointsForToken() {
|
||||||
|
TokenClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/XXXXXX/endpoints").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_endpoints.json", APPLICATION_JSON)).build())
|
||||||
|
.getTokenClient();
|
||||||
|
Set<Endpoint> endpoints = client.listEndpointsForToken("XXXXXX");
|
||||||
|
|
||||||
|
assertEquals(endpoints, ImmutableSet.of(
|
||||||
|
Endpoint.builder().publicURL(URI.create("https://csnode.jclouds.org/v2.0/"))
|
||||||
|
.adminURL(URI.create("https://csnode.jclouds.org:35357/v2.0/"))
|
||||||
|
.region("region-a.geo-1").versionId("2.0").build()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEndpointsForTokenFailNotFound() {
|
||||||
|
TokenClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/tokens/XXXXXX/endpoints").build(),
|
||||||
|
standardResponseBuilder(404).build())
|
||||||
|
.getTokenClient();
|
||||||
|
assertTrue(client.listEndpointsForToken("XXXXXX").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 1.1 (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-1.1
|
||||||
|
*
|
||||||
|
* 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.features;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
import static org.testng.AssertJUnit.assertTrue;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
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.BaseKeystoneClientLiveTest;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests TokenClient
|
||||||
|
*
|
||||||
|
* @author Adam Lowe
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "TokenClientLiveTest", singleThreaded = true)
|
||||||
|
public class TokenClientLiveTest extends BaseKeystoneClientLiveTest {
|
||||||
|
|
||||||
|
protected String token;
|
||||||
|
|
||||||
|
// Get the token currently in use (there's currently no listTokens())
|
||||||
|
@BeforeMethod
|
||||||
|
public void grabToken() {
|
||||||
|
AuthenticateRequest ar = keystoneContext.getUtils().getInjector().getInstance(AuthenticateRequest.class);
|
||||||
|
HttpRequest test = ar.filter(HttpRequest.builder().method("GET").endpoint(URI.create(endpoint)).build());
|
||||||
|
token = Iterables.getOnlyElement(test.getHeaders().get("X-Auth-Token"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testToken() {
|
||||||
|
|
||||||
|
TokenClient client = keystoneContext.getApi().getTokenClient();
|
||||||
|
assertTrue(client.isValid(token));
|
||||||
|
Token result = client.get(token);
|
||||||
|
assertNotNull(result);
|
||||||
|
assertEquals(result.getId(), token);
|
||||||
|
assertNotNull(result.getTenant());
|
||||||
|
|
||||||
|
User user = client.getUserOfToken(token);
|
||||||
|
assertNotNull(user);
|
||||||
|
assertNotNull(user.getId());
|
||||||
|
assertNotNull(user.getName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInvalidToken() {
|
||||||
|
|
||||||
|
TokenClient client = keystoneContext.getApi().getTokenClient();
|
||||||
|
assertFalse(client.isValid("thisisnotarealtoken!"));
|
||||||
|
assertNull(client.get("thisisnotarealtoken!"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTokenEndpoints() {
|
||||||
|
|
||||||
|
TokenClient client = keystoneContext.getApi().getTokenClient();
|
||||||
|
Set<Endpoint> endpoints = client.listEndpointsForToken(token);
|
||||||
|
assertNotNull(endpoints);
|
||||||
|
assertFalse(endpoints.isEmpty());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testInvalidTokenEndpoints() {
|
||||||
|
|
||||||
|
TokenClient client = keystoneContext.getApi().getTokenClient();
|
||||||
|
assertTrue(client.listEndpointsForToken("thisisnotarealtoken!").isEmpty());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,21 +22,19 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.http.HttpRequest;
|
|
||||||
import org.jclouds.http.HttpResponse;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.KeystoneClient;
|
import org.jclouds.openstack.keystone.v2_0.KeystoneClient;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.MediaType;
|
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestClientExpectTest;
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneRestClientExpectTest;
|
||||||
import org.jclouds.openstack.v2_0.domain.Link;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,53 +42,128 @@ import com.google.common.collect.ImmutableSet;
|
||||||
*
|
*
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
*/
|
*/
|
||||||
|
@Test(testName = "UserClientExpectTest")
|
||||||
public class UserClientExpectTest extends BaseKeystoneRestClientExpectTest<KeystoneClient> {
|
public class UserClientExpectTest extends BaseKeystoneRestClientExpectTest<KeystoneClient> {
|
||||||
|
|
||||||
public void testGetApiMetaData() {
|
public void testListUsers() {
|
||||||
ServiceClient client = requestsSendResponses(
|
UserClient client = requestsSendResponses(
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
HttpRequest.builder().method("GET").endpoint(URI.create(endpoint + "/v2.0/")).
|
standardRequestBuilder(endpoint + "/v2.0/users").build(),
|
||||||
headers(ImmutableMultimap.of("Accept", APPLICATION_JSON)).build(),
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_list.json", APPLICATION_JSON)).build())
|
||||||
HttpResponse.builder().statusCode(200).
|
.getUserClient();
|
||||||
payload(payloadFromResourceWithContentType("/api_metadata.json", APPLICATION_JSON)).build())
|
Set<User> users = client.list();
|
||||||
.getServiceClientForRegion("region-a.geo-1");
|
assertNotNull(users);
|
||||||
ApiMetadata metadata = client.getApiMetadata();
|
assertFalse(users.isEmpty());
|
||||||
assertNotNull(metadata);
|
|
||||||
assertEquals(metadata.getId(), "v2.0");
|
|
||||||
|
|
||||||
ApiMetadata expected = ApiMetadata.builder().id("v2.0")
|
Set<User> expected = ImmutableSet.of(
|
||||||
.links(ImmutableSet.of(Link.builder().relation(Link.Relation.SELF).href(URI.create("http://172.16.89.140:5000/v2.0/")).build(),
|
User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
||||||
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("text/html").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/content/")).build(),
|
User.builder().name("glance").id("3f6c1c9ba993495ead7d2eb2192e284f").build(),
|
||||||
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("application/pdf").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf")).build()
|
User.builder().name("demo").id("667b2e1420604df8b67cd8ea57d4ee64").build(),
|
||||||
))
|
User.builder().name("admin").id("2b9b606181634ae9ac86fd95a8bc2cde").build()
|
||||||
.status("beta")
|
|
||||||
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-11-19T00:00:00Z"))
|
|
||||||
.mediaTypes(ImmutableSet.of(
|
|
||||||
MediaType.builder().base("application/json").type("application/vnd.openstack.identity-v2.0+json").build(),
|
|
||||||
MediaType.builder().base("application/xml").type("application/vnd.openstack.identity-v2.0+xml").build()
|
|
||||||
))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
assertEquals(metadata, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testListTenants() {
|
|
||||||
ServiceClient client = requestsSendResponses(
|
|
||||||
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
|
||||||
HttpRequest.builder().method("GET").endpoint(URI.create(endpoint + "/v2.0/tenants")).
|
|
||||||
headers(ImmutableMultimap.of("Accept", APPLICATION_JSON, "X-Auth-Token", authToken)).build(),
|
|
||||||
HttpResponse.builder().statusCode(200).
|
|
||||||
payload(payloadFromResourceWithContentType("/tenant_list.json", APPLICATION_JSON)).build())
|
|
||||||
.getServiceClientForRegion("region-a.geo-1");
|
|
||||||
Set<Tenant> tenants = client.listTenants();
|
|
||||||
assertNotNull(tenants);
|
|
||||||
assertFalse(tenants.isEmpty());
|
|
||||||
|
|
||||||
Set<Tenant> expected = ImmutableSet.of(
|
|
||||||
Tenant.builder().name("demo").id("05d1dc7af71646deba64cfc17b81bec0").build(),
|
|
||||||
Tenant.builder().name("admin").id("7aa2e17ec29f44d193c48feaba0852cc").build()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assertEquals(tenants, expected);
|
assertEquals(users, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = AuthorizationException.class)
|
||||||
|
public void testListUsersFailNotAuth() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users").build(),
|
||||||
|
standardResponseBuilder(401).build()).getUserClient();
|
||||||
|
client.list();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUser() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/e021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getUserClient();
|
||||||
|
User user = client.get("e021dfd758eb44a89f1c57c8ef3be8e2");
|
||||||
|
assertNotNull(user);
|
||||||
|
assertEquals(user, User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserFailNotFound() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/f021dfd758eb44a89f1c57c8ef3be8e2").build(),
|
||||||
|
standardResponseBuilder(404).build()).getUserClient();
|
||||||
|
assertNull(client.get("f021dfd758eb44a89f1c57c8ef3be8e2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserByName() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users?name=nova").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_details.json", APPLICATION_JSON)).build())
|
||||||
|
.getUserClient();
|
||||||
|
User user = client.getByName("nova");
|
||||||
|
assertNotNull(user);
|
||||||
|
assertEquals(user, User.builder().name("nova").id("e021dfd758eb44a89f1c57c8ef3be8e2").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUserByNameFailNotFound() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users?name=fred").build(),
|
||||||
|
standardResponseBuilder(404).build()).getUserClient();
|
||||||
|
assertNull(client.getByName("fred"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListRolesOfUser() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_role_list.json", APPLICATION_JSON)).build())
|
||||||
|
.getUserClient();
|
||||||
|
Set<Role> roles = client.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f");
|
||||||
|
assertNotNull(roles);
|
||||||
|
assertFalse(roles.isEmpty());
|
||||||
|
assertEquals(roles, ImmutableSet.of(
|
||||||
|
Role.builder().id("79cada5c02814b57a52e0eed4dd388cb").name("admin").build()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListRolesOfUserFailNotFound() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/4f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(404).build()).getUserClient();
|
||||||
|
assertTrue(client.listRolesOfUser("4f6c1c9ba993495ead7d2eb2192e284f").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = HttpResponseException.class)
|
||||||
|
public void testListRolesOfUserFailNotImplemented() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/5f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(501).build()).getUserClient();
|
||||||
|
assertTrue(client.listRolesOfUser("5f6c1c9ba993495ead7d2eb2192e284f").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListRolesOfUserInTenant() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(200).payload(payloadFromResourceWithContentType("/user_tenant_role_list.json", APPLICATION_JSON)).build())
|
||||||
|
.getUserClient();
|
||||||
|
Set<Role> roles = client.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f");
|
||||||
|
assertNotNull(roles);
|
||||||
|
assertFalse(roles.isEmpty());
|
||||||
|
assertEquals(roles, ImmutableSet.of(
|
||||||
|
Role.builder().id("31c451195aac49b386039341e2c92a16").name("KeystoneServiceAdmin").build(),
|
||||||
|
Role.builder().id("79cada5c02814b57a52e0eed4dd388cb").name("admin").build(),
|
||||||
|
Role.builder().id("6ea17ddd37a6447794cb0e164d4db894").name("KeystoneAdmin").build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListRolesOfUserInTenantFailNotFound() {
|
||||||
|
UserClient client = requestsSendResponses(
|
||||||
|
keystoneAuthWithUsernameAndPassword, responseWithKeystoneAccess,
|
||||||
|
standardRequestBuilder(endpoint + "/v2.0/users/3f6c1c9ba993495ead7d2eb2192e284f/roles").build(),
|
||||||
|
standardResponseBuilder(404).build()).getUserClient();
|
||||||
|
assertTrue(client.listRolesOfUser("3f6c1c9ba993495ead7d2eb2192e284f").isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,15 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.keystone.v2_0.features;
|
package org.jclouds.openstack.keystone.v2_0.features;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
import org.jclouds.openstack.keystone.v2_0.domain.Role;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||||
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneClientLiveTest;
|
import org.jclouds.openstack.keystone.v2_0.internal.BaseKeystoneClientLiveTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -33,28 +35,58 @@ import org.testng.annotations.Test;
|
||||||
*
|
*
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "UserClientLiveTest")
|
@Test(groups = "live", testName = "UserClientLiveTest", singleThreaded = true)
|
||||||
public class UserClientLiveTest extends BaseKeystoneClientLiveTest {
|
public class UserClientLiveTest extends BaseKeystoneClientLiveTest {
|
||||||
|
|
||||||
public void testGetApiMetaData() {
|
public void testUsers() {
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
ApiMetadata result = keystoneContext.getApi().getServiceClientForRegion(regionId).getApiMetadata();
|
UserClient client = keystoneContext.getApi().getUserClient();
|
||||||
assertNotNull(result);
|
Set<User> users = client.list();
|
||||||
assertNotNull(result.getId());
|
assertNotNull(users);
|
||||||
assertNotNull(result.getStatus());
|
assertFalse(users.isEmpty());
|
||||||
assertNotNull(result.getUpdated());
|
for (User user : users) {
|
||||||
|
User aUser = client.get(user.getId());
|
||||||
|
assertEquals(aUser, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListTenants() {
|
public void testUserRolesOnTenant() {
|
||||||
for (String regionId : keystoneContext.getApi().getConfiguredRegions()) {
|
|
||||||
Set<Tenant> result = keystoneContext.getApi().getServiceClientForRegion(regionId).listTenants();
|
|
||||||
assertNotNull(result);
|
|
||||||
assertFalse(result.isEmpty());
|
|
||||||
|
|
||||||
for (Tenant tenant : result) {
|
UserClient client = keystoneContext.getApi().getUserClient();
|
||||||
assertNotNull(tenant.getId());
|
Set<User> users = client.list();
|
||||||
|
Set<Tenant> tenants = keystoneContext.getApi().getTenantClient().list();
|
||||||
|
|
||||||
|
for (User user : users) {
|
||||||
|
for (Tenant tenant : tenants) {
|
||||||
|
Set<Role> roles = client.listRolesOfUserOnTenant(user.getId(), tenant.getId());
|
||||||
|
for (Role role : roles) {
|
||||||
|
assertNotNull(role.getId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testListRolesOfUser() {
|
||||||
|
|
||||||
|
UserClient client = keystoneContext.getApi().getUserClient();
|
||||||
|
for (User user : client.list()) {
|
||||||
|
Set<Role> roles = client.listRolesOfUser(user.getId());
|
||||||
|
for (Role role : roles) {
|
||||||
|
assertNotNull(role.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUsersByName() {
|
||||||
|
|
||||||
|
UserClient client = keystoneContext.getApi().getUserClient();
|
||||||
|
for (User user : client.list()) {
|
||||||
|
User aUser = client.getByName(user.getName());
|
||||||
|
assertEquals(aUser, user);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,9 +28,9 @@ import org.testng.annotations.Test;
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "ReturnRegionTest")
|
@Test(groups = "unit", testName = "ReturnRegionOrProviderTest")
|
||||||
public class ReturnRegionTest {
|
public class ReturnRegionOrProviderTest {
|
||||||
private final ReturnRegion fn = new ReturnRegion();
|
private final ReturnRegionOrProvider fn = new ReturnRegionOrProvider("openstack-keystone");
|
||||||
|
|
||||||
public void testRegionNotNullReturnsRegion() {
|
public void testRegionNotNullReturnsRegion() {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
|
@ -39,15 +39,11 @@ public class ReturnRegionTest {
|
||||||
.build()), "LON");
|
.build()), "LON");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRegionNullNiceNPE() {
|
public void testRegionNullReturnsProvider() {
|
||||||
try {
|
assertEquals(
|
||||||
fn.apply(Endpoint.builder().versionId("1.0").publicURL(
|
fn.apply(Endpoint.builder().versionId("1.0").publicURL(
|
||||||
URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
|
URI.create("https://cdn3.clouddrive.com/v1/MossoCloudFS_83a9d536-2e25-4166-bd3b-a503a934f953"))
|
||||||
.build());
|
.build()), "openstack-keystone");
|
||||||
assert false;
|
|
||||||
} catch (NullPointerException e) {
|
|
||||||
assertEquals(e.getMessage(), "region");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -38,13 +38,13 @@ import com.google.common.reflect.TypeToken;
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live")
|
@Test(groups = "live")
|
||||||
public class BaseKeystoneClientLiveTest extends BaseContextLiveTest<RestContext<KeystoneClient, KeystoneAsyncClient>> {
|
public class BaseKeystoneClientLiveTest extends BaseContextLiveTest<RestContext<? extends KeystoneClient,? extends KeystoneAsyncClient>> {
|
||||||
|
|
||||||
public BaseKeystoneClientLiveTest() {
|
public BaseKeystoneClientLiveTest() {
|
||||||
provider = "openstack-keystone";
|
provider = "openstack-keystone";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected RestContext<KeystoneClient, KeystoneAsyncClient> keystoneContext;
|
protected RestContext<? extends KeystoneClient,? extends KeystoneAsyncClient> keystoneContext;
|
||||||
|
|
||||||
@BeforeGroups(groups = { "integration", "live" })
|
@BeforeGroups(groups = { "integration", "live" })
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,7 +67,7 @@ public class BaseKeystoneClientLiveTest extends BaseContextLiveTest<RestContext<
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TypeToken<RestContext<KeystoneClient, KeystoneAsyncClient>> contextType() {
|
protected TypeToken<RestContext<? extends KeystoneClient,? extends KeystoneAsyncClient>> contextType() {
|
||||||
return KeystoneApiMetadata.CONTEXT_TOKEN;
|
return KeystoneApiMetadata.CONTEXT_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,10 @@ import java.util.Properties;
|
||||||
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.apis.ApiMetadata;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.KeystoneApiMetadata;
|
||||||
import org.jclouds.openstack.v2_0.ServiceType;
|
import org.jclouds.openstack.v2_0.ServiceType;
|
||||||
import org.jclouds.rest.internal.BaseRestClientExpectTest;
|
import org.jclouds.rest.internal.BaseRestClientExpectTest;
|
||||||
|
|
||||||
|
@ -43,14 +45,14 @@ public class BaseKeystoneRestClientExpectTest<S> extends BaseRestClientExpectTes
|
||||||
protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey;
|
protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey;
|
||||||
protected String authToken;
|
protected String authToken;
|
||||||
protected HttpResponse responseWithKeystoneAccess;
|
protected HttpResponse responseWithKeystoneAccess;
|
||||||
protected String endpoint = "https://csnode.jclouds.org";
|
protected String endpoint = "http://localhost:5000";
|
||||||
|
|
||||||
public BaseKeystoneRestClientExpectTest() {
|
public BaseKeystoneRestClientExpectTest() {
|
||||||
provider = "openstack-keystone";
|
provider = "openstack-keystone";
|
||||||
keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity,
|
keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity,
|
||||||
credential);
|
credential);
|
||||||
keystoneAuthWithAccessKeyAndSecretKey = KeystoneFixture.INSTANCE.initialAuthWithAccessKeyAndSecretKey(identity,
|
keystoneAuthWithAccessKeyAndSecretKey = KeystoneFixture.INSTANCE.initialAuthWithAccessKeyAndSecretKey(identity,
|
||||||
credential);
|
credential);
|
||||||
|
|
||||||
authToken = KeystoneFixture.INSTANCE.getAuthToken();
|
authToken = KeystoneFixture.INSTANCE.getAuthToken();
|
||||||
responseWithKeystoneAccess = KeystoneFixture.INSTANCE.responseWithAccess();
|
responseWithKeystoneAccess = KeystoneFixture.INSTANCE.responseWithAccess();
|
||||||
|
@ -59,9 +61,9 @@ public class BaseKeystoneRestClientExpectTest<S> extends BaseRestClientExpectTes
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpRequest.Builder standardRequestBuilder(String endpoint) {
|
protected HttpRequest.Builder standardRequestBuilder(String endpoint) {
|
||||||
return HttpRequest.builder().method("GET")
|
return HttpRequest.builder().method("GET").headers(
|
||||||
.headers(ImmutableMultimap.of("Accept", MediaType.APPLICATION_JSON, "X-Auth-Token", authToken))
|
ImmutableMultimap.of("Accept", MediaType.APPLICATION_JSON, "X-Auth-Token", authToken)).endpoint(
|
||||||
.endpoint(URI.create(endpoint));
|
URI.create(endpoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpResponse.Builder standardResponseBuilder(int status) {
|
protected HttpResponse.Builder standardResponseBuilder(int status) {
|
||||||
|
@ -77,7 +79,13 @@ public class BaseKeystoneRestClientExpectTest<S> extends BaseRestClientExpectTes
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HttpRequestComparisonType compareHttpRequestAsType(HttpRequest input) {
|
protected HttpRequestComparisonType compareHttpRequestAsType(HttpRequest input) {
|
||||||
return Objects.equal("HEAD", input.getMethod()) ? HttpRequestComparisonType.DEFAULT : HttpRequestComparisonType.JSON;
|
return Objects.equal("HEAD", input.getMethod()) ? HttpRequestComparisonType.DEFAULT
|
||||||
|
: HttpRequestComparisonType.JSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ApiMetadata createApiMetadata() {
|
||||||
|
return new KeystoneApiMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,17 +85,23 @@ public class ParseAccessTest extends BaseItemParserTest<Access> {
|
||||||
.tenantId("3456")
|
.tenantId("3456")
|
||||||
.publicURL(URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"))
|
.publicURL(URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"))
|
||||||
.region("az-1.region-a.geo-1")
|
.region("az-1.region-a.geo-1")
|
||||||
.versionId("1.1").build(),
|
.versionId("1.1")
|
||||||
|
.versionInfo(URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/"))
|
||||||
|
.versionList(URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com")).build(),
|
||||||
Endpoint.builder()
|
Endpoint.builder()
|
||||||
.tenantId("3456")
|
.tenantId("3456")
|
||||||
.publicURL(URI.create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"))
|
.publicURL(URI.create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"))
|
||||||
.region("az-2.region-a.geo-1")
|
.region("az-2.region-a.geo-1")
|
||||||
.versionId("1.1").build(),
|
.versionId("1.1")
|
||||||
|
.versionInfo(URI.create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v1.1/"))
|
||||||
|
.versionList(URI.create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com")).build(),
|
||||||
Endpoint.builder()
|
Endpoint.builder()
|
||||||
.tenantId("3456")
|
.tenantId("3456")
|
||||||
.publicURL(URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"))
|
.publicURL(URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"))
|
||||||
.region("az-3.region-a.geo-1")
|
.region("az-3.region-a.geo-1")
|
||||||
.versionId("1.1").build()).build(),
|
.versionId("1.1")
|
||||||
|
.versionInfo(URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v1.1/"))
|
||||||
|
.versionList(URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com")).build()).build(),
|
||||||
|
|
||||||
Service.builder().name("Quantum Service").type("network").endpoints(
|
Service.builder().name("Quantum Service").type("network").endpoints(
|
||||||
Endpoint.builder()
|
Endpoint.builder()
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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.parse;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.json.BaseItemParserTest;
|
||||||
|
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.Role;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Service;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Tenant;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.Token;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.domain.User;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ParseAccessTest")
|
||||||
|
public class ParseRackspaceAccessTest extends BaseItemParserTest<Access> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/raxAuth.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SelectJson("access")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Access expected() {
|
||||||
|
return Access.builder().token(
|
||||||
|
Token.builder().expires(new SimpleDateFormatDateService().iso8601DateParse("2012-06-06T20:56:47.000-05:00"))
|
||||||
|
.id("Auth_4f173437e4b013bee56d1007").tenant(
|
||||||
|
Tenant.builder().id("40806637803162").name("40806637803162").build())
|
||||||
|
.build()).user(
|
||||||
|
User.builder().id("54321").name("joe").roles(
|
||||||
|
Role.builder().id("3").name("identity:user-admin").description("User Admin Role.")
|
||||||
|
.build()).build()).serviceCatalog(
|
||||||
|
|
||||||
|
Service.builder().name("cloudDatabases").type("rax:database").endpoints(
|
||||||
|
Endpoint.builder().tenantId("40806637803162").publicURL(
|
||||||
|
URI.create("https://dfw.databases.api.rackspacecloud.com/v1.0/40806637803162"))
|
||||||
|
.region("DFW").build(),
|
||||||
|
Endpoint.builder().tenantId("40806637803162").publicURL(
|
||||||
|
URI.create("https://ord.databases.api.rackspacecloud.com/v1.0/40806637803162"))
|
||||||
|
.region("ORD").build()).build(),
|
||||||
|
|
||||||
|
Service.builder().name("cloudServers").type("compute").endpoints(
|
||||||
|
Endpoint.builder().tenantId("40806637803162").publicURL(
|
||||||
|
URI.create("https://servers.api.rackspacecloud.com/v1.0/40806637803162"))
|
||||||
|
.versionId("1.0").versionInfo(URI.create("https://servers.api.rackspacecloud.com/v1.0"))
|
||||||
|
.versionList(URI.create("https://servers.api.rackspacecloud.com/")).build()).build(),
|
||||||
|
|
||||||
|
Service.builder().name("cloudFiles").type("object-store").endpoints(
|
||||||
|
Endpoint.builder().tenantId("MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22").publicURL(
|
||||||
|
URI.create("https://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22"))
|
||||||
|
.internalURL(
|
||||||
|
URI.create("https://snet-storage101.dfw1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22"))
|
||||||
|
.region("DFW").build()).build(),
|
||||||
|
|
||||||
|
Service.builder().name("cloudServersOpenStack").type("compute").endpoints(
|
||||||
|
Endpoint.builder().tenantId("40806637803162").publicURL(
|
||||||
|
URI.create("https://dfw.servers.api.rackspacecloud.com/v2/40806637803162"))
|
||||||
|
.versionInfo(URI.create("https://dfw.servers.api.rackspacecloud.com/v2"))
|
||||||
|
.versionList(URI.create("https://dfw.servers.api.rackspacecloud.com/"))
|
||||||
|
.versionId("2")
|
||||||
|
.region("DFW").build()).build(),
|
||||||
|
|
||||||
|
Service.builder().name("cloudLoadBalancers").type("rax:load-balancer").endpoints(
|
||||||
|
Endpoint.builder().tenantId("40806637803162").publicURL(
|
||||||
|
URI.create("https://ord.loadbalancers.api.rackspacecloud.com/v1.0/40806637803162"))
|
||||||
|
.region("ORD").build(),
|
||||||
|
Endpoint.builder().tenantId("40806637803162").publicURL(
|
||||||
|
URI.create("https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/40806637803162"))
|
||||||
|
.region("DFW").build()).build(),
|
||||||
|
|
||||||
|
Service.builder().name("cloudMonitoring").type("rax:monitor").endpoints(
|
||||||
|
Endpoint.builder().tenantId("40806637803162").publicURL(
|
||||||
|
URI.create("https://monitoring.api.rackspacecloud.com/v1.0/40806637803162")).build()).build(),
|
||||||
|
|
||||||
|
Service.builder().name("cloudDNS").type("dnsextension:dns").endpoints(
|
||||||
|
Endpoint.builder().tenantId("40806637803162").publicURL(
|
||||||
|
URI.create("https://dns.api.rackspacecloud.com/v1.0/40806637803162")).build()).build(),
|
||||||
|
|
||||||
|
Service.builder().name("cloudFilesCDN").type("rax:object-cdn").endpoints(
|
||||||
|
Endpoint.builder().tenantId("MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22").publicURL(
|
||||||
|
URI.create("https://cdn1.clouddrive.com/v1/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22"))
|
||||||
|
.region("DFW").build()).build()
|
||||||
|
).build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
* "License"); you may not use this file except in compliance
|
* "License"); you may not use this file except in compliance
|
||||||
* with the License. You may obtain a copy of the License at
|
* with the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing,
|
* Unless required by applicable law or agreed to in writing,
|
||||||
* software distributed under the License is distributed on an
|
* software distributed under the License is distributed on an
|
||||||
|
@ -33,30 +33,31 @@ import org.testng.annotations.Test;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Lowe
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "ParseApiMetadataTest")
|
@Test(groups = "unit", testName = "ParseApiMetadataTest")
|
||||||
public class ParseApiMetadataTest extends BaseItemParserTest<ApiMetadata> {
|
public class ParseRackspaceApiMetadataTest extends BaseItemParserTest<ApiMetadata> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String resource() {
|
public String resource() {
|
||||||
return "/apiMetadataResponse.json";
|
return "/raxVersion.json";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://docs.openstack.org/api/openstack-identity-service/2.0/content/Versions-d1e472.html
|
||||||
@Override
|
@Override
|
||||||
@SelectJson("version")
|
@SelectJson("version")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public ApiMetadata expected() {
|
public ApiMetadata expected() {
|
||||||
return ApiMetadata.builder().id("v2.0")
|
return ApiMetadata.builder().id("v2.0")
|
||||||
.links(ImmutableSet.of(Link.builder().relation(Link.Relation.SELF).href(URI.create("http://172.16.89.140:5000/v2.0/")).build(),
|
.links(ImmutableSet.of(Link.builder().relation(Link.Relation.SELF).href(URI.create("https://identity.api.rackspacecloud.com/v2.0")).build(),
|
||||||
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("text/html").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/content/")).build(),
|
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("application/pdf").href(URI.create("http://docs.rackspacecloud.com/auth/api/v2.0/auth-client-devguide-latest.pdf")).build(),
|
||||||
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("application/pdf").href(URI.create("http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf")).build()
|
Link.builder().relation(Link.Relation.DESCRIBEDBY).type("application/vnd.sun.wadl+xml").href(URI.create("http://docs.rackspacecloud.com/auth/api/v2.0/auth.wadl")).build()
|
||||||
))
|
))
|
||||||
.status("beta")
|
.status("BETA")
|
||||||
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-11-19T00:00:00Z"))
|
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-01-21T11:33:21-06:00"))
|
||||||
.mediaTypes(ImmutableSet.of(
|
.mediaTypes(ImmutableSet.of(
|
||||||
org.jclouds.openstack.keystone.v2_0.domain.MediaType.builder().base("application/json").type("application/vnd.openstack.identity-v2.0+json").build(),
|
org.jclouds.openstack.keystone.v2_0.domain.MediaType.builder().base("application/xml").type("application/vnd.openstack.identity+xml;version=2.0").build(),
|
||||||
org.jclouds.openstack.keystone.v2_0.domain.MediaType.builder().base("application/xml").type("application/vnd.openstack.identity-v2.0+xml").build()
|
org.jclouds.openstack.keystone.v2_0.domain.MediaType.builder().base("application/json").type("application/vnd.openstack.identity+json;version=2.0").build()
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
|
@ -22,11 +22,14 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
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.Access;
|
||||||
import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
|
import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
@ -36,19 +39,23 @@ import com.google.common.collect.Maps;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adam Lowe
|
* @author Adam Lowe
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "RegionIdToAdminURIFromAccessForTypeAndVersionSupplierTest")
|
@Test(groups = "unit", testName = "RegionIdToAdminURIFromAccessForTypeAndVersionTest")
|
||||||
public class RegionIdToAdminURIFromAccessForTypeAndVersionSupplierTest {
|
public class RegionIdToAdminURIFromAccessForTypeAndVersionTest {
|
||||||
private final RegionIdToAdminURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
|
private final RegionIdToAdminURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
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,
|
install(new FactoryModuleBuilder().implement(RegionIdToAdminURISupplier.class,
|
||||||
RegionIdToAdminURIFromAccessForTypeAndVersionSupplier.class).build(RegionIdToAdminURISupplier.Factory.class));
|
RegionIdToAdminURIFromAccessForTypeAndVersion.class).build(RegionIdToAdminURISupplier.Factory.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -70,4 +77,44 @@ public class RegionIdToAdminURIFromAccessForTypeAndVersionSupplierTest {
|
||||||
.<URI> supplierFunction()), map);
|
.<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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@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);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,71 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds 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 javax.inject.Singleton;
|
|
||||||
|
|
||||||
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.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.assistedinject.FactoryModuleBuilder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Test(groups = "unit", testName = "RegionIdToURIFromAccessForTypeAndVersionSupplierTest")
|
|
||||||
public class RegionIdToURIFromAccessForTypeAndVersionSupplierTest {
|
|
||||||
private final RegionIdToURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class,
|
|
||||||
RegionIdToURIFromAccessForTypeAndVersionSupplier.class).build(RegionIdToURISupplier.Factory.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
public Supplier<Access> provide() {
|
|
||||||
return Suppliers.ofInstance(new ParseAccessTest().expected());
|
|
||||||
}
|
|
||||||
}).getInstance(RegionIdToURISupplier.Factory.class);
|
|
||||||
|
|
||||||
public void testRegionMatches() {
|
|
||||||
assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.0").get(), Suppliers
|
|
||||||
.<URI> supplierFunction()), ImmutableMap.of());
|
|
||||||
assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.1").get(), Suppliers
|
|
||||||
.<URI> supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"),
|
|
||||||
"az-2.region-a.geo-1", URI.create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"),
|
|
||||||
"az-3.region-a.geo-1", URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456")));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public Supplier<Access> provide() {
|
||||||
|
return Suppliers.ofInstance(new ParseAccessTest().expected());
|
||||||
|
}
|
||||||
|
}).getInstance(RegionIdToURISupplier.Factory.class);
|
||||||
|
|
||||||
|
public void testRegionMatches() {
|
||||||
|
assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.0").get(), Suppliers
|
||||||
|
.<URI> supplierFunction()), ImmutableMap.of());
|
||||||
|
assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.1").get(), Suppliers
|
||||||
|
.<URI> supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI
|
||||||
|
.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"), "az-2.region-a.geo-1", URI
|
||||||
|
.create("https://az-2.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456"), "az-3.region-a.geo-1", URI
|
||||||
|
.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v1.1/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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@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")));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,12 +21,15 @@ package org.jclouds.openstack.keystone.v2_0.suppliers;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
import org.jclouds.location.suppliers.ZoneIdToURISupplier;
|
import org.jclouds.location.suppliers.ZoneIdToURISupplier;
|
||||||
import org.jclouds.openstack.keystone.v2_0.domain.Access;
|
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.ParseAccessTest;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.parse.ParseRackspaceAccessTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
@ -36,19 +39,23 @@ import com.google.common.collect.Maps;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "ZoneIdToURIFromAccessForTypeAndVersionSupplierTest")
|
@Test(groups = "unit", testName = "ZoneIdToURIFromAccessForTypeAndVersionSupplierTest")
|
||||||
public class ZoneIdToURIFromAccessForTypeAndVersionSupplierTest {
|
public class ZoneIdToURIFromAccessForTypeAndVersionTest {
|
||||||
private final ZoneIdToURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
|
private final ZoneIdToURISupplier.Factory factory = Guice.createInjector(new AbstractModule() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
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,
|
install(new FactoryModuleBuilder().implement(ZoneIdToURISupplier.class,
|
||||||
ZoneIdToURIFromAccessForTypeAndVersionSupplier.class).build(ZoneIdToURISupplier.Factory.class));
|
ZoneIdToURIFromAccessForTypeAndVersion.class).build(ZoneIdToURISupplier.Factory.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@ -68,4 +75,40 @@ public class ZoneIdToURIFromAccessForTypeAndVersionSupplierTest {
|
||||||
"az-3.region-a.geo-1", URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456")));
|
"az-3.region-a.geo-1", URI.create("https://az-3.region-a.geo-1.compute.hpcloudsvc.com/v1.1/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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@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")));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1 +0,0 @@
|
||||||
{"version": {"status": "beta", "updated": "2011-11-19T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v2.0+json"}, {"base": "application/xml", "type": "application/vnd.openstack.identity-v2.0+xml"}], "id": "v2.0", "links": [{"href": "http://172.16.89.140:5000/v2.0/", "rel": "self"}, {"href": "http://docs.openstack.org/api/openstack-identity-service/2.0/content/", "type": "text/html", "rel": "describedby"}, {"href": "http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf", "type": "application/pdf", "rel": "describedby"}]}}
|
|
|
@ -1 +0,0 @@
|
||||||
{"version": {"status": "beta", "updated": "2011-11-19T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v2.0+json"}, {"base": "application/xml", "type": "application/vnd.openstack.identity-v2.0+xml"}], "id": "v2.0", "links": [{"href": "http://172.16.89.140:5000/v2.0/", "rel": "self"}, {"href": "http://docs.openstack.org/api/openstack-identity-service/2.0/content/", "type": "text/html", "rel": "describedby"}, {"href": "http://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf", "type": "application/pdf", "rel": "describedby"}]}}
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
{
|
||||||
|
"access": {
|
||||||
|
"token": {
|
||||||
|
"id": "Auth_4f173437e4b013bee56d1007",
|
||||||
|
"expires": "2012-06-06T20:56:47.000-05:00",
|
||||||
|
"tenant": {
|
||||||
|
"id": "40806637803162",
|
||||||
|
"name": "40806637803162"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serviceCatalog": [{
|
||||||
|
"endpoints": [{
|
||||||
|
"region": "DFW",
|
||||||
|
"tenantId": "40806637803162",
|
||||||
|
"publicURL": "https:\/\/dfw.databases.api.rackspacecloud.com\/v1.0\/40806637803162"
|
||||||
|
}, {
|
||||||
|
"region": "ORD",
|
||||||
|
"tenantId": "40806637803162",
|
||||||
|
"publicURL": "https:\/\/ord.databases.api.rackspacecloud.com\/v1.0\/40806637803162"
|
||||||
|
}],
|
||||||
|
"name": "cloudDatabases",
|
||||||
|
"type": "rax:database"
|
||||||
|
}, {
|
||||||
|
"endpoints": [{
|
||||||
|
"tenantId": "40806637803162",
|
||||||
|
"publicURL": "https:\/\/servers.api.rackspacecloud.com\/v1.0\/40806637803162",
|
||||||
|
"versionInfo": "https:\/\/servers.api.rackspacecloud.com\/v1.0",
|
||||||
|
"versionList": "https:\/\/servers.api.rackspacecloud.com\/",
|
||||||
|
"versionId": "1.0"
|
||||||
|
}],
|
||||||
|
"name": "cloudServers",
|
||||||
|
"type": "compute"
|
||||||
|
}, {
|
||||||
|
"endpoints": [{
|
||||||
|
"region": "DFW",
|
||||||
|
"tenantId": "MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22",
|
||||||
|
"publicURL": "https:\/\/storage101.dfw1.clouddrive.com\/v1\/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22",
|
||||||
|
"internalURL": "https:\/\/snet-storage101.dfw1.clouddrive.com\/v1\/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22"
|
||||||
|
}],
|
||||||
|
"name": "cloudFiles",
|
||||||
|
"type": "object-store"
|
||||||
|
}, {
|
||||||
|
"endpoints": [{
|
||||||
|
"region": "DFW",
|
||||||
|
"tenantId": "40806637803162",
|
||||||
|
"publicURL": "https:\/\/dfw.servers.api.rackspacecloud.com\/v2\/40806637803162",
|
||||||
|
"versionInfo": "https:\/\/dfw.servers.api.rackspacecloud.com\/v2",
|
||||||
|
"versionList": "https:\/\/dfw.servers.api.rackspacecloud.com\/",
|
||||||
|
"versionId": "2"
|
||||||
|
}],
|
||||||
|
"name": "cloudServersOpenStack",
|
||||||
|
"type": "compute"
|
||||||
|
}, {
|
||||||
|
"endpoints": [{
|
||||||
|
"region": "ORD",
|
||||||
|
"tenantId": "40806637803162",
|
||||||
|
"publicURL": "https:\/\/ord.loadbalancers.api.rackspacecloud.com\/v1.0\/40806637803162"
|
||||||
|
}, {
|
||||||
|
"region": "DFW",
|
||||||
|
"tenantId": "40806637803162",
|
||||||
|
"publicURL": "https:\/\/dfw.loadbalancers.api.rackspacecloud.com\/v1.0\/40806637803162"
|
||||||
|
}],
|
||||||
|
"name": "cloudLoadBalancers",
|
||||||
|
"type": "rax:load-balancer"
|
||||||
|
}, {
|
||||||
|
"endpoints": [{
|
||||||
|
"tenantId": "40806637803162",
|
||||||
|
"publicURL": "https:\/\/monitoring.api.rackspacecloud.com\/v1.0\/40806637803162"
|
||||||
|
}],
|
||||||
|
"name": "cloudMonitoring",
|
||||||
|
"type": "rax:monitor"
|
||||||
|
}, {
|
||||||
|
"endpoints": [{
|
||||||
|
"tenantId": "40806637803162",
|
||||||
|
"publicURL": "https:\/\/dns.api.rackspacecloud.com\/v1.0\/40806637803162"
|
||||||
|
}],
|
||||||
|
"name": "cloudDNS",
|
||||||
|
"type": "dnsextension:dns"
|
||||||
|
}, {
|
||||||
|
"endpoints": [{
|
||||||
|
"region": "DFW",
|
||||||
|
"tenantId": "MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22",
|
||||||
|
"publicURL": "https:\/\/cdn1.clouddrive.com\/v1\/MossoCloudFS_dc1f419c-5059-4c87-a389-3f2e33a77b22"
|
||||||
|
}],
|
||||||
|
"name": "cloudFilesCDN",
|
||||||
|
"type": "rax:object-cdn"
|
||||||
|
}],
|
||||||
|
"user": {
|
||||||
|
"id": "54321",
|
||||||
|
"roles": [{
|
||||||
|
"id": "3",
|
||||||
|
"description": "User Admin Role.",
|
||||||
|
"name": "identity:user-admin"
|
||||||
|
}],
|
||||||
|
"name": "joe"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"version": {
|
||||||
|
"id": "v2.0",
|
||||||
|
"updated": "2012-01-21T11:33:21-06:00",
|
||||||
|
"status": "BETA",
|
||||||
|
"links": [{
|
||||||
|
"rel": "self",
|
||||||
|
"href": "https:\/\/identity.api.rackspacecloud.com\/v2.0"
|
||||||
|
}, {
|
||||||
|
"rel": "describedby",
|
||||||
|
"type": "application\/pdf",
|
||||||
|
"href": "http:\/\/docs.rackspacecloud.com\/auth\/api\/v2.0\/auth-client-devguide-latest.pdf"
|
||||||
|
}, {
|
||||||
|
"rel": "describedby",
|
||||||
|
"type": "application\/vnd.sun.wadl+xml",
|
||||||
|
"href": "http:\/\/docs.rackspacecloud.com\/auth\/api\/v2.0\/auth.wadl"
|
||||||
|
}],
|
||||||
|
"media-types": {
|
||||||
|
"values": [{
|
||||||
|
"base": "application\/xml",
|
||||||
|
"type": "application\/vnd.openstack.identity+xml;version=2.0"
|
||||||
|
}, {
|
||||||
|
"base": "application\/json",
|
||||||
|
"type": "application\/vnd.openstack.identity+json;version=2.0"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.nova.v1_1;
|
package org.jclouds.openstack.nova.v1_1;
|
||||||
|
|
||||||
|
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.v2_0.config.KeystoneProperties.SERVICE_TYPE;
|
||||||
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.VERSION;
|
import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.VERSION;
|
||||||
import static org.jclouds.openstack.nova.v1_1.config.NovaProperties.AUTO_ALLOCATE_FLOATING_IPS;
|
import static org.jclouds.openstack.nova.v1_1.config.NovaProperties.AUTO_ALLOCATE_FLOATING_IPS;
|
||||||
|
@ -29,6 +30,8 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.apis.ApiMetadata;
|
import org.jclouds.apis.ApiMetadata;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.KeystoneAuthenticationModuleForZones;
|
||||||
import org.jclouds.openstack.nova.v1_1.compute.config.NovaComputeServiceContextModule;
|
import org.jclouds.openstack.nova.v1_1.compute.config.NovaComputeServiceContextModule;
|
||||||
import org.jclouds.openstack.nova.v1_1.config.NovaRestClientModule;
|
import org.jclouds.openstack.nova.v1_1.config.NovaRestClientModule;
|
||||||
import org.jclouds.openstack.v2_0.ServiceType;
|
import org.jclouds.openstack.v2_0.ServiceType;
|
||||||
|
@ -73,6 +76,8 @@ public class NovaApiMetadata extends BaseRestApiMetadata {
|
||||||
properties.setProperty("jclouds.ssh.retry-auth", "true");
|
properties.setProperty("jclouds.ssh.retry-auth", "true");
|
||||||
|
|
||||||
properties.setProperty(SERVICE_TYPE, ServiceType.COMPUTE);
|
properties.setProperty(SERVICE_TYPE, ServiceType.COMPUTE);
|
||||||
|
properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
|
||||||
|
|
||||||
// TODO: this doesn't actually do anything yet.
|
// TODO: this doesn't actually do anything yet.
|
||||||
properties.setProperty(VERSION, "2.0");
|
properties.setProperty(VERSION, "2.0");
|
||||||
|
|
||||||
|
@ -95,7 +100,7 @@ public class NovaApiMetadata extends BaseRestApiMetadata {
|
||||||
.defaultEndpoint("http://localhost:5000")
|
.defaultEndpoint("http://localhost:5000")
|
||||||
.defaultProperties(NovaApiMetadata.defaultProperties())
|
.defaultProperties(NovaApiMetadata.defaultProperties())
|
||||||
.view(TypeToken.of(ComputeServiceContext.class))
|
.view(TypeToken.of(ComputeServiceContext.class))
|
||||||
.defaultModules(ImmutableSet.<Class<? extends Module>>of(NovaRestClientModule.class, NovaComputeServiceContextModule.class));
|
.defaultModules(ImmutableSet.<Class<? extends Module>>of(KeystoneAuthenticationModuleForZones.class, NovaRestClientModule.class, NovaComputeServiceContextModule.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||||
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
|
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
|
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
import org.jclouds.openstack.nova.v1_1.domain.Extension;
|
||||||
|
@ -126,12 +125,6 @@ public class NovaRestClientModule extends RestClientModule<NovaClient, NovaAsync
|
||||||
@Override
|
@Override
|
||||||
protected void installLocations() {
|
protected void installLocations() {
|
||||||
super.installLocations();
|
super.installLocations();
|
||||||
// TODO: select this from KeystoneProperties.VERSION; note you select from
|
|
||||||
// a guice provided
|
|
||||||
// property, so it will have to come from somewhere else, maybe we move
|
|
||||||
// this to the the
|
|
||||||
// ContextBuilder
|
|
||||||
install(KeystoneAuthenticationModule.forZones());
|
|
||||||
bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON);
|
bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.location.suppliers;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.location.suppliers.fromconfig.RegionIdToURIFromConfigurationOrDefaultToProvider;
|
import org.jclouds.location.suppliers.fromconfig.RegionIdToURIFromConfigurationOrDefaultToProvider;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
@ -41,11 +42,11 @@ public interface RegionIdToURISupplier extends Supplier<Map<String, Supplier<URI
|
||||||
* type of the api, according to the provider. ex. {@code compute} {@code
|
* type of the api, according to the provider. ex. {@code compute} {@code
|
||||||
* object-store}
|
* object-store}
|
||||||
* @param apiVersion
|
* @param apiVersion
|
||||||
* version of the api
|
* version of the api, or null if not available
|
||||||
* @return regions mapped to default uri
|
* @return regions mapped to default uri
|
||||||
*/
|
*/
|
||||||
RegionIdToURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType,
|
RegionIdToURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType,
|
||||||
@Assisted("apiVersion") String apiVersion);
|
@Nullable @Assisted("apiVersion") String apiVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,6 +21,7 @@ package org.jclouds.location.suppliers;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.location.suppliers.fromconfig.ZoneIdToURIFromConfigurationOrDefaultToProvider;
|
import org.jclouds.location.suppliers.fromconfig.ZoneIdToURIFromConfigurationOrDefaultToProvider;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
@ -41,10 +42,10 @@ public interface ZoneIdToURISupplier extends Supplier<Map<String, Supplier<URI>>
|
||||||
* type of the api, according to the provider. ex. {@code compute} {@code
|
* type of the api, according to the provider. ex. {@code compute} {@code
|
||||||
* object-store}
|
* object-store}
|
||||||
* @param apiVersion
|
* @param apiVersion
|
||||||
* version of the api
|
* version of the api, or null if not present
|
||||||
* @return regions mapped to default uri
|
* @return regions mapped to default uri
|
||||||
*/
|
*/
|
||||||
ZoneIdToURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType,
|
ZoneIdToURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType,
|
||||||
@Assisted("apiVersion") String apiVersion);
|
@Nullable @Assisted("apiVersion") String apiVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.glance.v1_0;
|
package org.jclouds.openstack.glance.v1_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.v2_0.config.KeystoneProperties.SERVICE_TYPE;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -25,7 +26,9 @@ import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.apis.ApiMetadata;
|
import org.jclouds.apis.ApiMetadata;
|
||||||
import org.jclouds.openstack.glance.v1_0.config.GlanceRestClientModule;
|
import org.jclouds.openstack.glance.v1_0.config.GlanceRestClientModule;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.KeystoneAuthenticationModuleForRegions;
|
||||||
import org.jclouds.openstack.v2_0.ServiceType;
|
import org.jclouds.openstack.v2_0.ServiceType;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.rest.internal.BaseRestApiMetadata;
|
import org.jclouds.rest.internal.BaseRestApiMetadata;
|
||||||
|
@ -64,6 +67,8 @@ public class GlanceApiMetadata extends BaseRestApiMetadata {
|
||||||
public static Properties defaultProperties() {
|
public static Properties defaultProperties() {
|
||||||
Properties properties = BaseRestApiMetadata.defaultProperties();
|
Properties properties = BaseRestApiMetadata.defaultProperties();
|
||||||
properties.setProperty(SERVICE_TYPE, ServiceType.IMAGE);
|
properties.setProperty(SERVICE_TYPE, ServiceType.IMAGE);
|
||||||
|
properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
|
||||||
|
|
||||||
// TODO: this doesn't actually do anything yet.
|
// TODO: this doesn't actually do anything yet.
|
||||||
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
||||||
return properties;
|
return properties;
|
||||||
|
@ -81,7 +86,7 @@ public class GlanceApiMetadata extends BaseRestApiMetadata {
|
||||||
.version("1.0")
|
.version("1.0")
|
||||||
.defaultEndpoint("http://localhost:5000")
|
.defaultEndpoint("http://localhost:5000")
|
||||||
.defaultProperties(GlanceApiMetadata.defaultProperties())
|
.defaultProperties(GlanceApiMetadata.defaultProperties())
|
||||||
.defaultModules(ImmutableSet.<Class<? extends Module>>of(GlanceRestClientModule.class));
|
.defaultModules(ImmutableSet.<Class<? extends Module>>of(KeystoneAuthenticationModuleForRegions.class, GlanceRestClientModule.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.jclouds.openstack.glance.v1_0.GlanceClient;
|
||||||
import org.jclouds.openstack.glance.v1_0.features.ImageAsyncClient;
|
import org.jclouds.openstack.glance.v1_0.features.ImageAsyncClient;
|
||||||
import org.jclouds.openstack.glance.v1_0.features.ImageClient;
|
import org.jclouds.openstack.glance.v1_0.features.ImageClient;
|
||||||
import org.jclouds.openstack.glance.v1_0.handlers.GlanceErrorHandler;
|
import org.jclouds.openstack.glance.v1_0.handlers.GlanceErrorHandler;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
|
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
|
|
||||||
|
@ -59,17 +58,6 @@ public class GlanceRestClientModule extends RestClientModule<GlanceClient, Glanc
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void installLocations() {
|
|
||||||
// TODO: select this from KeystoneProperties.VERSION; note you select from
|
|
||||||
// a guice provided
|
|
||||||
// property, so it will have to come from somewhere else, maybe we move
|
|
||||||
// this to the the
|
|
||||||
// ContextBuilder
|
|
||||||
install(KeystoneAuthenticationModule.forRegions());
|
|
||||||
super.installLocations();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bindErrorHandlers() {
|
protected void bindErrorHandlers() {
|
||||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GlanceErrorHandler.class);
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GlanceErrorHandler.class);
|
||||||
|
|
|
@ -18,13 +18,16 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.quantum.v1_0;
|
package org.jclouds.openstack.quantum.v1_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.v2_0.config.KeystoneProperties.SERVICE_TYPE;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.apis.ApiMetadata;
|
import org.jclouds.apis.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.KeystoneAuthenticationModuleForRegions;
|
||||||
import org.jclouds.openstack.quantum.v1_0.config.QuantumRestClientModule;
|
import org.jclouds.openstack.quantum.v1_0.config.QuantumRestClientModule;
|
||||||
import org.jclouds.openstack.v2_0.ServiceType;
|
import org.jclouds.openstack.v2_0.ServiceType;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
|
@ -63,6 +66,8 @@ public class QuantumApiMetadata extends BaseRestApiMetadata {
|
||||||
public static Properties defaultProperties() {
|
public static Properties defaultProperties() {
|
||||||
Properties properties = BaseRestApiMetadata.defaultProperties();
|
Properties properties = BaseRestApiMetadata.defaultProperties();
|
||||||
properties.setProperty(SERVICE_TYPE, ServiceType.NETWORK);
|
properties.setProperty(SERVICE_TYPE, ServiceType.NETWORK);
|
||||||
|
properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
|
||||||
|
|
||||||
// TODO: this doesn't actually do anything yet.
|
// TODO: this doesn't actually do anything yet.
|
||||||
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
||||||
return properties;
|
return properties;
|
||||||
|
@ -80,7 +85,7 @@ public class QuantumApiMetadata extends BaseRestApiMetadata {
|
||||||
.version("1.0")
|
.version("1.0")
|
||||||
.defaultEndpoint("http://localhost:5000")
|
.defaultEndpoint("http://localhost:5000")
|
||||||
.defaultProperties(QuantumApiMetadata.defaultProperties())
|
.defaultProperties(QuantumApiMetadata.defaultProperties())
|
||||||
.defaultModules(ImmutableSet.<Class<? extends Module>>of(QuantumRestClientModule.class));
|
.defaultModules(ImmutableSet.<Class<? extends Module>>of(KeystoneAuthenticationModuleForRegions.class, QuantumRestClientModule.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -26,7 +26,6 @@ import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
|
|
||||||
import org.jclouds.openstack.quantum.v1_0.QuantumAsyncClient;
|
import org.jclouds.openstack.quantum.v1_0.QuantumAsyncClient;
|
||||||
import org.jclouds.openstack.quantum.v1_0.QuantumClient;
|
import org.jclouds.openstack.quantum.v1_0.QuantumClient;
|
||||||
import org.jclouds.openstack.quantum.v1_0.features.NetworkAsyncClient;
|
import org.jclouds.openstack.quantum.v1_0.features.NetworkAsyncClient;
|
||||||
|
@ -62,17 +61,6 @@ public class QuantumRestClientModule extends RestClientModule<QuantumClient, Qua
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void installLocations() {
|
|
||||||
// TODO: select this from KeystoneProperties.VERSION; note you select from
|
|
||||||
// a guice provided
|
|
||||||
// property, so it will have to come from somewhere else, maybe we move
|
|
||||||
// this to the the
|
|
||||||
// ContextBuilder
|
|
||||||
install(KeystoneAuthenticationModule.forRegions());
|
|
||||||
super.installLocations();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bindErrorHandlers() {
|
protected void bindErrorHandlers() {
|
||||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(QuantumErrorHandler.class);
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(QuantumErrorHandler.class);
|
||||||
|
|
|
@ -18,13 +18,16 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.openstack.swift.v1;
|
package org.jclouds.openstack.swift.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.v2_0.config.KeystoneProperties.SERVICE_TYPE;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.apis.ApiMetadata;
|
import org.jclouds.apis.ApiMetadata;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.KeystoneAuthenticationModuleForRegions;
|
||||||
import org.jclouds.openstack.swift.v1.config.SwiftRestClientModule;
|
import org.jclouds.openstack.swift.v1.config.SwiftRestClientModule;
|
||||||
import org.jclouds.openstack.v2_0.ServiceType;
|
import org.jclouds.openstack.v2_0.ServiceType;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
|
@ -64,6 +67,8 @@ public class SwiftApiMetadata extends BaseRestApiMetadata {
|
||||||
public static Properties defaultProperties() {
|
public static Properties defaultProperties() {
|
||||||
Properties properties = BaseRestApiMetadata.defaultProperties();
|
Properties properties = BaseRestApiMetadata.defaultProperties();
|
||||||
properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE);
|
properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE);
|
||||||
|
properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
|
||||||
|
|
||||||
// TODO: this doesn't actually do anything yet.
|
// TODO: this doesn't actually do anything yet.
|
||||||
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
||||||
return properties;
|
return properties;
|
||||||
|
@ -81,7 +86,7 @@ public class SwiftApiMetadata extends BaseRestApiMetadata {
|
||||||
.version("1.0")
|
.version("1.0")
|
||||||
.defaultEndpoint("http://localhost:5000")
|
.defaultEndpoint("http://localhost:5000")
|
||||||
.defaultProperties(SwiftApiMetadata.defaultProperties())
|
.defaultProperties(SwiftApiMetadata.defaultProperties())
|
||||||
.defaultModules(ImmutableSet.<Class<? extends Module>>of(SwiftRestClientModule.class));
|
.defaultModules(ImmutableSet.<Class<? extends Module>>of(KeystoneAuthenticationModuleForRegions.class, SwiftRestClientModule.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -26,7 +26,6 @@ import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
|
|
||||||
import org.jclouds.openstack.swift.v1.SwiftAsyncClient;
|
import org.jclouds.openstack.swift.v1.SwiftAsyncClient;
|
||||||
import org.jclouds.openstack.swift.v1.SwiftClient;
|
import org.jclouds.openstack.swift.v1.SwiftClient;
|
||||||
import org.jclouds.openstack.swift.v1.features.AccountAsyncClient;
|
import org.jclouds.openstack.swift.v1.features.AccountAsyncClient;
|
||||||
|
@ -65,17 +64,6 @@ public class SwiftRestClientModule extends RestClientModule<SwiftClient, SwiftAs
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void installLocations() {
|
|
||||||
// TODO: select this from KeystoneProperties.VERSION; note you select from
|
|
||||||
// a guice provided
|
|
||||||
// property, so it will have to come from somewhere else, maybe we move
|
|
||||||
// this to the the
|
|
||||||
// ContextBuilder
|
|
||||||
install(KeystoneAuthenticationModule.forRegions());
|
|
||||||
super.installLocations();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bindErrorHandlers() {
|
protected void bindErrorHandlers() {
|
||||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(SwiftErrorHandler.class);
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(SwiftErrorHandler.class);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.hpcloud.compute.config.HPCloudComputeServiceContextModule;
|
import org.jclouds.hpcloud.compute.config.HPCloudComputeServiceContextModule;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaApiMetadata;
|
import org.jclouds.openstack.nova.v1_1.NovaApiMetadata;
|
||||||
import org.jclouds.openstack.nova.v1_1.config.NovaRestClientModule;
|
import org.jclouds.openstack.nova.v1_1.config.NovaRestClientModule;
|
||||||
import org.jclouds.providers.ProviderMetadata;
|
import org.jclouds.providers.ProviderMetadata;
|
||||||
|
@ -68,7 +69,7 @@ public class HPCloudComputeProviderMetadata extends BaseProviderMetadata {
|
||||||
// deallocating ip addresses can take a while
|
// deallocating ip addresses can take a while
|
||||||
properties.setProperty(TIMEOUT_NODE_TERMINATED, 60 * 1000 + "");
|
properties.setProperty(TIMEOUT_NODE_TERMINATED, 60 * 1000 + "");
|
||||||
|
|
||||||
properties.setProperty(CREDENTIAL_TYPE, "apiAccessKeyCredentials");
|
properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.API_ACCESS_KEY_CREDENTIALS);
|
||||||
properties.setProperty(AUTO_ALLOCATE_FLOATING_IPS, "true");
|
properties.setProperty(AUTO_ALLOCATE_FLOATING_IPS, "true");
|
||||||
properties.setProperty(AUTO_GENERATE_KEYPAIRS, "true");
|
properties.setProperty(AUTO_GENERATE_KEYPAIRS, "true");
|
||||||
properties.setProperty(TEMPLATE, "osFamily=UBUNTU,osVersionMatches=1[012].[01][04],os64Bit=true,locationId=az-2.region-a.geo-1");
|
properties.setProperty(TEMPLATE, "osFamily=UBUNTU,osVersionMatches=1[012].[01][04],os64Bit=true,locationId=az-2.region-a.geo-1");
|
||||||
|
|
|
@ -28,7 +28,9 @@ import org.jclouds.apis.ApiMetadata;
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
import org.jclouds.hpcloud.objectstorage.blobstore.config.HPCloudObjectStorageBlobStoreContextModule;
|
import org.jclouds.hpcloud.objectstorage.blobstore.config.HPCloudObjectStorageBlobStoreContextModule;
|
||||||
import org.jclouds.hpcloud.objectstorage.config.HPCloudObjectStorageRestClientModule;
|
import org.jclouds.hpcloud.objectstorage.config.HPCloudObjectStorageRestClientModule;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties;
|
||||||
|
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.KeystoneAuthenticationModuleForRegions;
|
||||||
import org.jclouds.openstack.services.ServiceType;
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
import org.jclouds.openstack.swift.SwiftApiMetadata;
|
import org.jclouds.openstack.swift.SwiftApiMetadata;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
|
@ -73,7 +75,7 @@ public class HPCloudObjectStorageApiMetadata extends BaseRestApiMetadata {
|
||||||
properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE);
|
properties.setProperty(SERVICE_TYPE, ServiceType.OBJECT_STORE);
|
||||||
// TODO: this doesn't actually do anything yet.
|
// TODO: this doesn't actually do anything yet.
|
||||||
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
properties.setProperty(KeystoneProperties.VERSION, "2.0");
|
||||||
properties.setProperty(CREDENTIAL_TYPE, "apiAccessKeyCredentials");
|
properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.API_ACCESS_KEY_CREDENTIALS);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +91,7 @@ public class HPCloudObjectStorageApiMetadata extends BaseRestApiMetadata {
|
||||||
.documentation(URI.create("https://build.hpcloud.com/object-storage/api"))
|
.documentation(URI.create("https://build.hpcloud.com/object-storage/api"))
|
||||||
.defaultProperties(HPCloudObjectStorageApiMetadata.defaultProperties())
|
.defaultProperties(HPCloudObjectStorageApiMetadata.defaultProperties())
|
||||||
.view(TypeToken.of(BlobStoreContext.class))
|
.view(TypeToken.of(BlobStoreContext.class))
|
||||||
.defaultModules(ImmutableSet.<Class<? extends Module>>of(HPCloudObjectStorageRestClientModule.class, HPCloudObjectStorageBlobStoreContextModule.class));
|
.defaultModules(ImmutableSet.<Class<? extends Module>>of(KeystoneAuthenticationModuleForRegions.class, HPCloudObjectStorageRestClientModule.class, HPCloudObjectStorageBlobStoreContextModule.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -38,7 +38,6 @@ import org.jclouds.http.annotation.ServerError;
|
||||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||||
import org.jclouds.location.suppliers.RegionIdToURISupplier;
|
import org.jclouds.location.suppliers.RegionIdToURISupplier;
|
||||||
import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
|
|
||||||
import org.jclouds.openstack.services.ServiceType;
|
import org.jclouds.openstack.services.ServiceType;
|
||||||
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
import org.jclouds.openstack.swift.CommonSwiftAsyncClient;
|
||||||
import org.jclouds.openstack.swift.CommonSwiftClient;
|
import org.jclouds.openstack.swift.CommonSwiftClient;
|
||||||
|
@ -73,13 +72,6 @@ public class HPCloudObjectStorageRestClientModule extends
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void installLocations() {
|
|
||||||
super.installLocations();
|
|
||||||
// TODO: select this from KeystoneProperties.VERSION;
|
|
||||||
install(KeystoneAuthenticationModule.forRegions());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void bindErrorHandlers() {
|
protected void bindErrorHandlers() {
|
||||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseSwiftErrorFromHttpResponse.class);
|
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(ParseSwiftErrorFromHttpResponse.class);
|
||||||
|
|
Loading…
Reference in New Issue