Updating to work with latest JClouds. Tests are borked, but that is unrelate to the API changes and the core code works. I'll fix the tests soon too

This commit is contained in:
Chris Custine 2011-02-13 12:32:24 -07:00
parent 32c7ee4b31
commit 6d9cf7321e
13 changed files with 116 additions and 26 deletions

View File

@ -74,7 +74,7 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-log4j</artifactId> <artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
<scope>test</scope> <scope>test</scope>
@ -93,4 +93,72 @@
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
</dependencies> </dependencies>
<!--TODO: This is borrowed from another module, the chef properties need to be filled in for the tests to work-->
<!--
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>none</exclude>
</excludes>
<includes>
<include>**/*LiveTest.java</include>
</includes>
<systemProperties>
<property>
<name>jclouds.compute.provider</name>
<value>${jclouds.compute.provider}</value>
</property>
<property>
<name>jclouds.compute.endpoint</name>
<value>${jclouds.compute.endpoint}</value>
</property>
<property>
<name>jclouds.compute.identity</name>
<value>${jclouds.compute.identity}</value>
</property>
<property>
<name>jclouds.compute.credential</name>
<value>${jclouds.compute.credential}</value>
</property>
<property>
<name>jclouds.compute.tag</name>
<value>${jclouds.compute.tag}</value>
</property>
<property>
<name>jclouds.compute.credential</name>
<value>${jclouds.compute.credential}</value>
</property>
<property>
<name>jclouds.chef.credential.pem</name>
<value>${jclouds.chef.credential.pem}</value>
</property>
<property>
<name>jclouds.chef.endpoint</name>
<value>${jclouds.chef.endpoint}</value>
</property>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
-->
</project> </project>

View File

@ -43,7 +43,7 @@ import com.google.common.primitives.Bytes;
public class BindChecksumsToJsonPayload extends BindToStringPayload { public class BindChecksumsToJsonPayload extends BindToStringPayload {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void bindToRequest(HttpRequest request, Object input) { public HttpRequest bindToRequest( HttpRequest request, Object input ) {
checkArgument(checkNotNull(input, "input") instanceof Set, "this binder is only valid for Set!"); checkArgument(checkNotNull(input, "input") instanceof Set, "this binder is only valid for Set!");
Set<List<Byte>> md5s = (Set<List<Byte>>) input; Set<List<Byte>> md5s = (Set<List<Byte>>) input;
@ -57,6 +57,7 @@ public class BindChecksumsToJsonPayload extends BindToStringPayload {
builder.append("}}"); builder.append("}}");
super.bindToRequest(request, builder.toString()); super.bindToRequest(request, builder.toString());
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
return request;
} }
} }

View File

@ -34,9 +34,10 @@ import org.jclouds.rest.binders.BindToStringPayload;
public class BindClientnameToJsonPayload extends BindToStringPayload { public class BindClientnameToJsonPayload extends BindToStringPayload {
@Override @Override
public void bindToRequest(HttpRequest request, Object payload) { public HttpRequest bindToRequest( HttpRequest request, Object payload ) {
super.bindToRequest(request, String.format("{\"clientname\":\"%s\"}", payload)); super.bindToRequest(request, String.format("{\"clientname\":\"%s\"}", payload));
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
return request;
} }
} }

View File

@ -34,10 +34,11 @@ import org.jclouds.rest.binders.BindToStringPayload;
public class BindGenerateKeyForClientToJsonPayload extends BindToStringPayload { public class BindGenerateKeyForClientToJsonPayload extends BindToStringPayload {
@Override @Override
public void bindToRequest(HttpRequest request, Object payload) { public HttpRequest bindToRequest( HttpRequest request, Object payload ) {
super.bindToRequest(request, String.format("{\"clientname\":\"%s\", \"private_key\": true}", super.bindToRequest(request, String.format("{\"clientname\":\"%s\", \"private_key\": true}",
payload)); payload));
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
return request;
} }
} }

View File

@ -34,9 +34,10 @@ import org.jclouds.rest.binders.BindToStringPayload;
public class BindIsCompletedToJsonPayload extends BindToStringPayload { public class BindIsCompletedToJsonPayload extends BindToStringPayload {
@Override @Override
public void bindToRequest(HttpRequest request, Object value) { public HttpRequest bindToRequest( HttpRequest request, Object value ) {
super.bindToRequest(request, String.format("{\"is_completed\":\"%s\"}", value)); super.bindToRequest(request, String.format("{\"is_completed\":\"%s\"}", value));
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
return request;
} }
} }

View File

@ -34,9 +34,10 @@ import org.jclouds.rest.binders.BindToStringPayload;
public class BindNameToJsonPayload extends BindToStringPayload { public class BindNameToJsonPayload extends BindToStringPayload {
@Override @Override
public void bindToRequest(HttpRequest request, Object payload) { public HttpRequest bindToRequest( HttpRequest request, Object payload ) {
super.bindToRequest(request, String.format("{\"name\":\"%s\"}", payload)); super.bindToRequest(request, String.format("{\"name\":\"%s\"}", payload));
request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
return request;
} }
} }

View File

@ -20,10 +20,14 @@
package org.jclouds.chef.filters; package org.jclouds.chef.filters;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.Constants.PROPERTY_IDENTITY; import static org.jclouds.Constants.PROPERTY_IDENTITY;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -32,6 +36,11 @@ import javax.inject.Named;
import javax.inject.Provider; import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.crypto.Crypto; import org.jclouds.crypto.Crypto;
import org.jclouds.crypto.CryptoStreams; import org.jclouds.crypto.CryptoStreams;
@ -41,6 +50,7 @@ import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpUtils; import org.jclouds.http.HttpUtils;
import org.jclouds.http.internal.SignatureWire; import org.jclouds.http.internal.SignatureWire;
import org.jclouds.http.utils.ModifyRequest;
import org.jclouds.io.InputSuppliers; import org.jclouds.io.InputSuppliers;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import org.jclouds.io.Payloads; import org.jclouds.io.Payloads;
@ -92,30 +102,35 @@ public class SignedHeaderAuth implements HttpRequestFilter {
this.utils = utils; this.utils = utils;
} }
public void filter(HttpRequest request) throws HttpException { public HttpRequest filter( HttpRequest request ) throws HttpException {
String contentHash = hashBody(request.getPayload()); String contentHash = hashBody(request.getPayload());
request.getHeaders().replaceValues("X-Ops-Content-Hash", Collections.singletonList(contentHash)); Multimap<String, String> headers = ArrayListMultimap.create();
headers.put( "X-Ops-Content-Hash", contentHash );
String timestamp = timeStampProvider.get(); String timestamp = timeStampProvider.get();
String toSign = createStringToSign(request.getMethod(), hashPath(request.getEndpoint().getPath()), contentHash, String toSign = createStringToSign(request.getMethod(), hashPath(request.getEndpoint().getPath()), contentHash,
timestamp); timestamp);
request.getHeaders().replaceValues("X-Ops-Userid", Collections.singletonList(userId)); headers.put("X-Ops-Userid", userId);
request.getHeaders().replaceValues("X-Ops-Sign", Collections.singletonList(SIGNING_DESCRIPTION)); headers.put( "X-Ops-Sign", SIGNING_DESCRIPTION );
calculateAndReplaceAuthorizationHeaders(request, toSign); request = calculateAndReplaceAuthorizationHeaders( request, toSign );
request.getHeaders().replaceValues("X-Ops-Timestamp", Collections.singletonList(timestamp)); headers.put( "X-Ops-Timestamp", timestamp );
utils.logRequest( signatureLog, request, "<<" ); utils.logRequest( signatureLog, request, "<<" );
return ModifyRequest.putHeaders(request, headers);
} }
@VisibleForTesting @VisibleForTesting
void calculateAndReplaceAuthorizationHeaders(HttpRequest request, String toSign) throws HttpException { HttpRequest calculateAndReplaceAuthorizationHeaders( HttpRequest request, String toSign ) throws HttpException {
String signature = sign(toSign); String signature = sign(toSign);
if (signatureWire.enabled()) if (signatureWire.enabled())
signatureWire.input(Utils.toInputStream(signature)); signatureWire.input(Utils.toInputStream(signature));
String[] signatureLines = Iterables.toArray(Splitter.fixedLength(60).split(signature), String.class); String[] signatureLines = Iterables.toArray(Splitter.fixedLength(60).split(signature), String.class);
Multimap<String, String> headers = ArrayListMultimap.create();
for (int i = 0; i < signatureLines.length; i++) { for (int i = 0; i < signatureLines.length; i++) {
request.getHeaders().replaceValues("X-Ops-Authorization-" + (i + 1), headers.put("X-Ops-Authorization-" + (i + 1), signatureLines[i]);
Collections.singletonList(signatureLines[i]));
} }
return ModifyRequest.putHeaders( request, headers );
} }
public String createStringToSign(String request, String hashedPath, String contentHash, String timestamp) { public String createStringToSign(String request, String hashedPath, String contentHash, String timestamp) {

View File

@ -40,7 +40,7 @@ import org.jclouds.chef.domain.Client;
import org.jclouds.crypto.Pems; import org.jclouds.crypto.Pems;
import org.jclouds.io.Payload; import org.jclouds.io.Payload;
import org.jclouds.json.Json; import org.jclouds.json.Json;
import org.jclouds.rest.annotations.Provider; import org.jclouds.location.Provider;
import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.scriptbuilder.domain.Statement;

View File

@ -57,8 +57,8 @@ public class ChefClientErrorRetryHandler implements HttpRetryHandler {
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) { public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
if (command.getFailureCount() > retryCountLimit) if (command.getFailureCount() > retryCountLimit)
return false; return false;
if (response.getStatusCode() == 400 && command.getRequest().getMethod().equals("PUT") if (response.getStatusCode() == 400 && command.getCurrentRequest().getMethod().equals("PUT")
&& command.getRequest().getEndpoint().getPath().indexOf("sandboxes") != -1) { && command.getCurrentRequest().getEndpoint().getPath().indexOf("sandboxes") != -1) {
if (response.getPayload() != null) { if (response.getPayload() != null) {
String error = new String(closeClientButKeepContentStream(response)); String error = new String(closeClientButKeepContentStream(response));
if (error != null && error.indexOf("was not uploaded") != -1) { if (error != null && error.indexOf("was not uploaded") != -1) {

View File

@ -55,7 +55,7 @@ public class ChefErrorHandler implements HttpErrorHandler {
String message = errorParser.apply(response); String message = errorParser.apply(response);
Exception exception = new HttpResponseException(command, response, message); Exception exception = new HttpResponseException(command, response, message);
try { try {
message = message != null ? message : String.format("%s -> %s", command.getRequest() message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest()
.getRequestLine(), response.getStatusLine()); .getRequestLine(), response.getStatusLine());
switch (response.getStatusCode()) { switch (response.getStatusCode()) {
case 401: case 401:
@ -63,7 +63,7 @@ public class ChefErrorHandler implements HttpErrorHandler {
exception = new AuthorizationException(message, exception); exception = new AuthorizationException(message, exception);
break; break;
case 404: case 404:
if (!command.getRequest().getMethod().equals("DELETE")) { if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
exception = new ResourceNotFoundException(message, exception); exception = new ResourceNotFoundException(message, exception);
} }
break; break;

View File

@ -20,7 +20,9 @@
package org.jclouds.chef.internal; package org.jclouds.chef.internal;
import java.net.URI; import java.net.URI;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -34,7 +36,7 @@ import org.jclouds.lifecycle.Closer;
import org.jclouds.rest.Utils; import org.jclouds.rest.Utils;
import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.rest.annotations.ApiVersion;
import org.jclouds.rest.annotations.Identity; import org.jclouds.rest.annotations.Identity;
import org.jclouds.rest.annotations.Provider; import org.jclouds.location.Provider;
import org.jclouds.rest.internal.RestContextImpl; import org.jclouds.rest.internal.RestContextImpl;
import com.google.inject.Injector; import com.google.inject.Injector;
@ -51,7 +53,7 @@ public class ChefContextImpl extends RestContextImpl<ChefClient, ChefAsyncClient
protected ChefContextImpl(Closer closer, Map<String, Credentials> credentialStore, Utils utils, Injector injector, protected ChefContextImpl(Closer closer, Map<String, Credentials> credentialStore, Utils utils, Injector injector,
TypeLiteral<ChefClient> syncApi, TypeLiteral<ChefAsyncClient> asyncApi, @Provider URI endpoint, TypeLiteral<ChefClient> syncApi, TypeLiteral<ChefAsyncClient> asyncApi, @Provider URI endpoint,
@Provider String provider, @Identity String identity, @ApiVersion String apiVersion, ChefService chefService) { @Provider String provider, @Identity String identity, @ApiVersion String apiVersion, ChefService chefService) {
super(closer, credentialStore, utils, injector, syncApi, asyncApi, endpoint, provider, identity, apiVersion); super(closer, credentialStore, utils, injector, syncApi, asyncApi, endpoint, provider, identity, apiVersion, null ); // Not sure what needs to go here for Chef
this.chefService = chefService; this.chefService = chefService;
} }

View File

@ -140,7 +140,7 @@ public class SignedHeaderAuthTest {
expected_string_to_sign); expected_string_to_sign);
assertEquals(signing_obj.sign(expected_string_to_sign), Joiner.on("").join(X_OPS_AUTHORIZATION_LINES)); assertEquals(signing_obj.sign(expected_string_to_sign), Joiner.on("").join(X_OPS_AUTHORIZATION_LINES));
signing_obj.filter(request); request = signing_obj.filter(request);
Multimap<String, String> headersWithoutContentLength = LinkedHashMultimap.create(request.getHeaders()); Multimap<String, String> headersWithoutContentLength = LinkedHashMultimap.create(request.getHeaders());
headersWithoutContentLength.removeAll(HttpHeaders.CONTENT_LENGTH); headersWithoutContentLength.removeAll(HttpHeaders.CONTENT_LENGTH);
assertEquals(headersWithoutContentLength.values(), EXPECTED_SIGN_RESULT.values()); assertEquals(headersWithoutContentLength.values(), EXPECTED_SIGN_RESULT.values());
@ -152,7 +152,7 @@ public class SignedHeaderAuthTest {
URI host = URI.create("http://localhost/" + PATH); URI host = URI.create("http://localhost/" + PATH);
HttpRequest request = new HttpRequest(HttpMethod.DELETE, host); HttpRequest request = new HttpRequest(HttpMethod.DELETE, host);
signing_obj.filter(request); request = signing_obj.filter(request);
Multimap<String, String> headersWithoutContentLength = LinkedHashMultimap.create(request.getHeaders()); Multimap<String, String> headersWithoutContentLength = LinkedHashMultimap.create(request.getHeaders());
assertEquals(headersWithoutContentLength.entries(), EXPECTED_SIGN_RESULT_EMPTY.entries()); assertEquals(headersWithoutContentLength.entries(), EXPECTED_SIGN_RESULT_EMPTY.entries());
} }

View File

@ -103,7 +103,7 @@ public class ChefClientErrorRetryHandlerTest {
.newStringPayload("{\"error\":[\"Cannot update sandbox bfd68d4052f44053b2e593a33b5e1cd5: checksum 9b7c23369f4b576451216c39f214af6c was not uploaded\"]}")); .newStringPayload("{\"error\":[\"Cannot update sandbox bfd68d4052f44053b2e593a33b5e1cd5: checksum 9b7c23369f4b576451216c39f214af6c was not uploaded\"]}"));
expect(command.getFailureCount()).andReturn(0); expect(command.getFailureCount()).andReturn(0);
expect(command.getRequest()).andReturn(request).atLeastOnce(); expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
expect(retry.shouldRetryRequest(command, response)).andReturn(true); expect(retry.shouldRetryRequest(command, response)).andReturn(true);
replay(retry); replay(retry);