diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialType.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialType.java new file mode 100644 index 0000000000..c168ccc666 --- /dev/null +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/CredentialType.java @@ -0,0 +1,46 @@ +/** + * 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.checkNotNull; + +import com.google.common.base.CaseFormat; + +/** + * Configuration properties and constants used in Keystone connections. + * + * @author Adrian Cole + */ +public enum CredentialType { + + API_ACCESS_KEY_CREDENTIALS, + + PASSWORD_CREDENTIALS; + + @Override + public String toString() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()); + } + + public static CredentialType fromValue(String credentialType) { + return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(credentialType, + "credentialType"))); + } + +} diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeyStoneAuthenticationModule.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeyStoneAuthenticationModule.java index eb6e1b57d3..691f91eb1e 100644 --- a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeyStoneAuthenticationModule.java +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeyStoneAuthenticationModule.java @@ -24,7 +24,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; @@ -38,21 +37,19 @@ import org.jclouds.location.Provider; import org.jclouds.openstack.Authentication; import org.jclouds.openstack.keystone.v2_0.ServiceAsyncClient; import org.jclouds.openstack.keystone.v2_0.domain.Access; -import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials; +import org.jclouds.openstack.keystone.v2_0.functions.AuthenticateApiAccessKeyCredentials; +import org.jclouds.openstack.keystone.v2_0.functions.AuthenticatePasswordCredentials; import org.jclouds.openstack.keystone.v2_0.handlers.RetryOnRenew; import org.jclouds.rest.AsyncClientFactory; import com.google.common.base.Function; -import com.google.common.base.Splitter; import com.google.common.base.Supplier; -import com.google.common.base.Throwables; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; -import com.google.common.collect.Iterables; import com.google.inject.AbstractModule; +import com.google.inject.Inject; import com.google.inject.Provides; -import com.google.inject.TypeLiteral; /** * @@ -63,9 +60,8 @@ public class KeyStoneAuthenticationModule extends AbstractModule { @Override protected void configure() { - bind(new TypeLiteral>() { - }).to(GetAccess.class); bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(RetryOnRenew.class); + bind(CredentialType.class).toProvider(CredentialTypeFromPropertyOrDefault.class); } /** @@ -89,45 +85,48 @@ public class KeyStoneAuthenticationModule extends AbstractModule { return factory.create(ServiceAsyncClient.class); } - @Provides - @Provider - protected Credentials provideAuthenticationCredentials(@Named(Constants.PROPERTY_IDENTITY) String userOrApiKey, - @Named(Constants.PROPERTY_CREDENTIAL) String keyOrSecretKey) { - return new Credentials(userOrApiKey, keyOrSecretKey); + @Singleton + static class CredentialTypeFromPropertyOrDefault implements javax.inject.Provider { + /** + * use optional injection to supply a default value for credential type. so that we don't have + * to set a default property. + */ + @Inject(optional = true) + @Named(KeystoneProperties.CREDENTIAL_TYPE) + String credentialType = CredentialType.API_ACCESS_KEY_CREDENTIALS.toString(); + + @Override + public CredentialType get() { + return CredentialType.fromValue(credentialType); + } } + @Provides @Singleton - public static class GetAccess extends RetryOnTimeOutExceptionFunction { - - // passing factory here to avoid a circular dependency on - // OpenStackAuthAsyncClient resolving ServiceAsyncClient - @Inject - public GetAccess(final AsyncClientFactory factory) { - super(new Function() { - - @Override - public Access apply(Credentials input) { - // TODO: nice error messages, etc. - Iterable tenantIdUsername = Splitter.on(':').split(input.identity); - String tenantId = Iterables.get(tenantIdUsername, 0); - String username = Iterables.get(tenantIdUsername, 1); - PasswordCredentials passwordCredentials = PasswordCredentials.createWithUsernameAndPassword(username, - input.credential); - try { - return factory.create(ServiceAsyncClient.class).authenticateTenantWithCredentials(tenantId, - passwordCredentials).get(); - } catch (Exception e) { - throw Throwables.propagate(e); - } - } - - @Override - public String toString() { - return "authenticate()"; - } - }); - + protected Function authenticationMethodForCredentialType(CredentialType credentialType, + AuthenticatePasswordCredentials authenticatePasswordCredentials, + AuthenticateApiAccessKeyCredentials authenticateApiAccessKeyCredentials) { + Function authMethod; + switch (credentialType) { + 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 + // in. + return new RetryOnTimeOutExceptionFunction(authMethod); + } + + @Provides + @Provider + protected Credentials provideAuthenticationCredentials(@Named(Constants.PROPERTY_IDENTITY) String userOrAccessKey, + @Named(Constants.PROPERTY_CREDENTIAL) String keyOrSecretKey) { + return new Credentials(userOrAccessKey, keyOrSecretKey); } // TODO: what is the timeout of the session token? modify default accordingly diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneProperties.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneProperties.java new file mode 100644 index 0000000000..96c87f1ad0 --- /dev/null +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneProperties.java @@ -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 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.openstack.keystone.v2_0.config; + +/** + * Configuration properties and constants used in Keystone connections. + * + * @author Adrian Cole + */ +public interface KeystoneProperties { + + /** + * Type of credentials used to log into the auth service. + * + *

valid values

+ *
    + *
  • apiAccessKeyCredentials
  • + *
  • passwordCredentials
  • + *
+ * + * @see CredentialType + * @see + */ + public static final String CREDENTIAL_TYPE = "jclouds.keystone.credential-type"; + +} diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticateApiAccessKeyCredentials.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticateApiAccessKeyCredentials.java new file mode 100644 index 0000000000..04f40dce09 --- /dev/null +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticateApiAccessKeyCredentials.java @@ -0,0 +1,66 @@ +/** + * 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; + +import javax.inject.Inject; + +import org.jclouds.domain.Credentials; +import org.jclouds.openstack.keystone.v2_0.ServiceAsyncClient; +import org.jclouds.openstack.keystone.v2_0.domain.Access; +import org.jclouds.openstack.keystone.v2_0.domain.ApiAccessKeyCredentials; +import org.jclouds.rest.AsyncClientFactory; + +import com.google.common.base.Function; +import com.google.common.base.Splitter; +import com.google.common.base.Throwables; +import com.google.common.collect.Iterables; + +public class AuthenticateApiAccessKeyCredentials implements Function { + private final AsyncClientFactory factory; + + // passing factory here to avoid a circular dependency on + // OpenStackAuthAsyncClient resolving ServiceAsyncClient + @Inject + public AuthenticateApiAccessKeyCredentials(AsyncClientFactory factory) { + this.factory = factory; + } + + @Override + public Access apply(Credentials input) { + // TODO: tenantID may not be present + Iterable tenantIdUsernameOrAccessKey = Splitter.on(':').split(input.identity); + String tenantId = Iterables.get(tenantIdUsernameOrAccessKey, 0); + String usernameOrAccessKey = Iterables.get(tenantIdUsernameOrAccessKey, 1); + String passwordOrSecretKey = input.credential; + + ServiceAsyncClient client = factory.create(ServiceAsyncClient.class); + try { + ApiAccessKeyCredentials apiAccessKeyCredentials = ApiAccessKeyCredentials.createWithAccessKeyAndSecretKey( + usernameOrAccessKey, passwordOrSecretKey); + return client.authenticateTenantWithCredentials(tenantId, apiAccessKeyCredentials).get(); + } catch (Exception e) { + throw Throwables.propagate(e); + } + } + + @Override + public String toString() { + return "authenticateApiAccessKeyCredentials()"; + } +} \ No newline at end of file diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticatePasswordCredentials.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticatePasswordCredentials.java new file mode 100644 index 0000000000..90360c164b --- /dev/null +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/functions/AuthenticatePasswordCredentials.java @@ -0,0 +1,65 @@ +/** + * 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; + +import javax.inject.Inject; + +import org.jclouds.domain.Credentials; +import org.jclouds.openstack.keystone.v2_0.ServiceAsyncClient; +import org.jclouds.openstack.keystone.v2_0.domain.Access; +import org.jclouds.openstack.keystone.v2_0.domain.PasswordCredentials; +import org.jclouds.rest.AsyncClientFactory; + +import com.google.common.base.Function; +import com.google.common.base.Splitter; +import com.google.common.base.Throwables; +import com.google.common.collect.Iterables; + +public class AuthenticatePasswordCredentials implements Function { + private final AsyncClientFactory factory; + // passing factory here to avoid a circular dependency on + // OpenStackAuthAsyncClient resolving ServiceAsyncClient + @Inject + public AuthenticatePasswordCredentials(AsyncClientFactory factory) { + this.factory = factory; + } + + @Override + public Access apply(Credentials input) { + // TODO: tenantID may not be present + Iterable tenantIdUsernameOrAccessKey = Splitter.on(':').split(input.identity); + String tenantId = Iterables.get(tenantIdUsernameOrAccessKey, 0); + String usernameOrAccessKey = Iterables.get(tenantIdUsernameOrAccessKey, 1); + String passwordOrSecretKey = input.credential; + + ServiceAsyncClient client = factory.create(ServiceAsyncClient.class); + try { + PasswordCredentials passwordCredentials = PasswordCredentials.createWithUsernameAndPassword( + usernameOrAccessKey, passwordOrSecretKey); + return client.authenticateTenantWithCredentials(tenantId, passwordCredentials).get(); + } catch (Exception e) { + throw Throwables.propagate(e); + } + } + + @Override + public String toString() { + return "authenticatePasswordCredentials()"; + } +} \ No newline at end of file diff --git a/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeyStoneRestClientExpectTest.java b/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeyStoneRestClientExpectTest.java index ee45b8f308..d2954601ba 100644 --- a/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeyStoneRestClientExpectTest.java +++ b/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/internal/BaseKeyStoneRestClientExpectTest.java @@ -18,6 +18,7 @@ */ package org.jclouds.openstack.keystone.v2_0.internal; +import static java.lang.String.format; import java.net.URI; import org.jclouds.http.HttpRequest; @@ -35,21 +36,39 @@ import com.google.common.net.HttpHeaders; */ public class BaseKeyStoneRestClientExpectTest extends BaseRestClientExpectTest { - public BaseKeyStoneRestClientExpectTest() { - // tenantId:username - identity = "12346637803162:user@jclouds.org"; - credential = "Password1234"; - } + protected static final String tenantId = "12346637803162"; - protected HttpRequest initialAuth = HttpRequest + protected static final String username = "user@jclouds.org"; + protected static final String password = "Password1234"; + protected static final HttpRequest initialAuthWithPasswordCredentials = HttpRequest .builder() .method("POST") .endpoint(URI.create("http://localhost:5000/v2.0/tokens")) .headers(ImmutableMultimap.of(HttpHeaders.ACCEPT, "application/json")) .payload( payloadFromStringWithContentType( - "{\"auth\":{\"passwordCredentials\":{\"username\":\"user@jclouds.org\",\"password\":\"Password1234\"},\"tenantId\":\"12346637803162\"}}", - "application/json")).build(); + format( + "{\"auth\":{\"passwordCredentials\":{\"username\":\"%s\",\"password\":\"%s\"},\"tenantId\":\"%s\"}}", + username, password, tenantId), "application/json")).build(); + + protected static final String accessKey = "FH6FU8GMZFLKP5BUR2X1"; + protected static final String secretKey = "G4QWed0lh5SH7kBrcvOM1cHygKWk81EBt+Hr1dsl"; + protected static final HttpRequest initialAuthWithApiAccessKeyCredentials = HttpRequest + .builder() + .method("POST") + .endpoint(URI.create("http://localhost:5000/v2.0/tokens")) + .headers(ImmutableMultimap.of(HttpHeaders.ACCEPT, "application/json")) + .payload( + payloadFromStringWithContentType( + format( + "{\"auth\":{\"apiAccessKeyCredentials\":{\"accessKey\":\"%s\",\"secretKey\":\"%s\"},\"tenantId\":\"%s\"}}", + accessKey, secretKey, tenantId), "application/json")).build(); + + public BaseKeyStoneRestClientExpectTest() { + identity = tenantId + ":" + accessKey; + credential = secretKey; + } + protected String authToken = "Auth_4f173437e4b013bee56d1007"; diff --git a/core/src/test/java/org/jclouds/rest/BaseRestClientExpectTest.java b/core/src/test/java/org/jclouds/rest/BaseRestClientExpectTest.java index 831fa29a6d..bf8f63f97f 100644 --- a/core/src/test/java/org/jclouds/rest/BaseRestClientExpectTest.java +++ b/core/src/test/java/org/jclouds/rest/BaseRestClientExpectTest.java @@ -153,18 +153,19 @@ public abstract class BaseRestClientExpectTest { public Payload payloadFromResourceWithContentType(String resource, String contentType) { try { - return payloadFromStringWithContentType(Strings2.toStringAndClose(getClass().getResourceAsStream(resource)), contentType); + return payloadFromStringWithContentType(Strings2.toStringAndClose(getClass().getResourceAsStream(resource)), + contentType); } catch (IOException e) { throw Throwables.propagate(e); } } - public Payload payloadFromString(String payload) { + public static Payload payloadFromString(String payload) { return Payloads.newStringPayload(payload); } - public Payload payloadFromStringWithContentType(String payload, String contentType) { + public static Payload payloadFromStringWithContentType(String payload, String contentType) { Payload p = Payloads.newStringPayload(payload); p.getContentMetadata().setContentType(contentType); return p; @@ -347,9 +348,22 @@ public abstract class BaseRestClientExpectTest { @Override public HttpResponse apply(HttpRequest input) { - if (!(requestToResponse.containsKey(input))) + if (!(requestToResponse.containsKey(input))) { + + StringBuilder payload = new StringBuilder("\n"); + payload.append("the following request is not configured:\n"); + payload.append("----------------------------------------\n"); + payload.append(renderRequest(input)); + payload.append("----------------------------------------\n"); + payload.append("configured requests:\n"); + for (HttpRequest request : requestToResponse.keySet()) { + payload.append("----------------------------------------\n"); + payload.append(renderRequest(request)); + } return HttpResponse.builder().statusCode(500).message("no response configured for request").payload( - Payloads.newStringPayload(renderRequest(input))).build(); + Payloads.newStringPayload(payload.toString())).build(); + + } HttpResponse response = requestToResponse.get(input); // in case hashCode/equals doesn't do a full content check assertEquals(renderRequest(input), renderRequest(bimap.inverse().get(response))); diff --git a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/features/PasswordAuthenticationExpectTest.java b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/features/PasswordAuthenticationExpectTest.java new file mode 100644 index 0000000000..f69295cdf3 --- /dev/null +++ b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/features/PasswordAuthenticationExpectTest.java @@ -0,0 +1,73 @@ +/** + * 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.nova.v1_1.features; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; +import java.util.Properties; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.nova.v1_1.internal.BaseNovaRestClientExpectTest; +import org.jclouds.openstack.nova.v1_1.parse.ParseServerListTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; + +/** + * + * @see KeystoneProperties#CREDENTIAL_TYPE + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "PasswordAuthenticationExpectTest") +public class PasswordAuthenticationExpectTest extends BaseNovaRestClientExpectTest { + + public PasswordAuthenticationExpectTest() { + provider = "openstack-nova"; + identity = tenantId + ":" + username; + credential = password; + } + + /** + * this reflects the properties that a user would pass to createContext + */ + @Override + protected Properties setupProperties() { + Properties contextProperties = super.setupProperties(); + contextProperties.setProperty("jclouds.keystone.credential-type", "passwordCredentials"); + return contextProperties; + } + + public void testListServersWhenResponseIs2xx() throws Exception { + HttpRequest listServers = HttpRequest.builder().method("GET").endpoint( + URI.create("http://compute-1.jclouds.org:8774/v1.1/40806637803162/servers")).headers( + ImmutableMultimap. builder().put("Accept", "application/json").put("X-Auth-Token", + authToken).build()).build(); + + HttpResponse listServersResponse = HttpResponse.builder().statusCode(200).payload( + payloadFromResource("/server_list.json")).build(); + + ServerClient clientWhenServersExist = requestsSendResponses(initialAuthWithPasswordCredentials, + responseWithAccess, listServers, listServersResponse).getServerClient(); + + assertEquals(clientWhenServersExist.listServers().toString(), new ParseServerListTest().expected().toString()); + } + +} diff --git a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/features/ServerClientExpectTest.java b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/features/ServerClientExpectTest.java index 4c0d001517..33d047f857 100644 --- a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/features/ServerClientExpectTest.java +++ b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/features/ServerClientExpectTest.java @@ -27,49 +27,46 @@ public class ServerClientExpectTest extends BaseNovaRestClientExpectTest { } public void testListServersWhenResponseIs2xx() throws Exception { - HttpRequest listServers = HttpRequest.builder().method("GET") - .endpoint(URI.create("http://compute-1.jclouds.org:8774/v1.1/40806637803162/servers")) - .headers(ImmutableMultimap. builder() - .put("Accept", "application/json") - .put("X-Auth-Token", authToken).build()).build(); - + HttpRequest listServers = HttpRequest.builder().method("GET").endpoint( + URI.create("http://compute-1.jclouds.org:8774/v1.1/40806637803162/servers")).headers( + ImmutableMultimap. builder().put("Accept", "application/json").put("X-Auth-Token", + authToken).build()).build(); + HttpResponse listServersResponse = HttpResponse.builder().statusCode(200).payload( payloadFromResource("/server_list.json")).build(); - ServerClient clientWhenServersExist = requestsSendResponses(initialAuth, responseWithAccess, listServers, - listServersResponse).getServerClient(); + ServerClient clientWhenServersExist = requestsSendResponses(initialAuthWithApiAccessKeyCredentials, + responseWithAccess, listServers, listServersResponse).getServerClient(); assertEquals(clientWhenServersExist.listServers().toString(), new ParseServerListTest().expected().toString()); } public void testListServersWhenReponseIs404IsEmpty() throws Exception { - HttpRequest listServers = HttpRequest.builder().method("GET") - .endpoint(URI.create("http://compute-1.jclouds.org:8774/v1.1/40806637803162/servers")) - .headers(ImmutableMultimap. builder() - .put("Accept", "application/json") - .put("X-Auth-Token", authToken).build()).build(); - + HttpRequest listServers = HttpRequest.builder().method("GET").endpoint( + URI.create("http://compute-1.jclouds.org:8774/v1.1/40806637803162/servers")).headers( + ImmutableMultimap. builder().put("Accept", "application/json").put("X-Auth-Token", + authToken).build()).build(); + HttpResponse listServersResponse = HttpResponse.builder().statusCode(404).build(); - ServerClient clientWhenServersExist = requestsSendResponses(initialAuth, responseWithAccess, listServers, - listServersResponse).getServerClient(); + ServerClient clientWhenServersExist = requestsSendResponses(initialAuthWithApiAccessKeyCredentials, + responseWithAccess, listServers, listServersResponse).getServerClient(); assertTrue(clientWhenServersExist.listServers().isEmpty()); } - //TODO: gson deserializer for Multimap + // TODO: gson deserializer for Multimap public void testGetServerWhenResponseIs2xx() throws Exception { - HttpRequest listServers = HttpRequest.builder().method("GET") - .endpoint(URI.create("http://compute-1.jclouds.org:8774/v1.1/40806637803162/servers/foo")) - .headers(ImmutableMultimap. builder() - .put("Accept", "application/json") - .put("X-Auth-Token", authToken).build()).build(); - + HttpRequest listServers = HttpRequest.builder().method("GET").endpoint( + URI.create("http://compute-1.jclouds.org:8774/v1.1/40806637803162/servers/foo")).headers( + ImmutableMultimap. builder().put("Accept", "application/json").put("X-Auth-Token", + authToken).build()).build(); + HttpResponse listServersResponse = HttpResponse.builder().statusCode(200).payload( payloadFromResource("/server_details.json")).build(); - ServerClient clientWhenServersExist = requestsSendResponses(initialAuth, responseWithAccess, listServers, - listServersResponse).getServerClient(); + ServerClient clientWhenServersExist = requestsSendResponses(initialAuthWithApiAccessKeyCredentials, + responseWithAccess, listServers, listServersResponse).getServerClient(); assertEquals(clientWhenServersExist.getServer("foo").toString(), new ParseServerTest().expected().toString()); }