diff --git a/apis/chef/pom.xml b/apis/chef/pom.xml index b045ffb740..878a19778a 100644 --- a/apis/chef/pom.xml +++ b/apis/chef/pom.xml @@ -74,7 +74,7 @@ test - ${project.groupId} + org.jclouds.driver jclouds-log4j ${project.version} test @@ -93,4 +93,72 @@ true + + + diff --git a/apis/chef/src/main/java/org/jclouds/chef/binders/BindChecksumsToJsonPayload.java b/apis/chef/src/main/java/org/jclouds/chef/binders/BindChecksumsToJsonPayload.java index e03eab4bed..a93cbc71d8 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/binders/BindChecksumsToJsonPayload.java +++ b/apis/chef/src/main/java/org/jclouds/chef/binders/BindChecksumsToJsonPayload.java @@ -43,7 +43,7 @@ import com.google.common.primitives.Bytes; public class BindChecksumsToJsonPayload extends BindToStringPayload { @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!"); Set> md5s = (Set>) input; @@ -57,6 +57,7 @@ public class BindChecksumsToJsonPayload extends BindToStringPayload { builder.append("}}"); super.bindToRequest(request, builder.toString()); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); + return request; } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/binders/BindClientnameToJsonPayload.java b/apis/chef/src/main/java/org/jclouds/chef/binders/BindClientnameToJsonPayload.java index 6ed8ffd961..0f08a92b8c 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/binders/BindClientnameToJsonPayload.java +++ b/apis/chef/src/main/java/org/jclouds/chef/binders/BindClientnameToJsonPayload.java @@ -34,9 +34,10 @@ import org.jclouds.rest.binders.BindToStringPayload; public class BindClientnameToJsonPayload extends BindToStringPayload { @Override - public void bindToRequest(HttpRequest request, Object payload) { + public HttpRequest bindToRequest( HttpRequest request, Object payload ) { super.bindToRequest(request, String.format("{\"clientname\":\"%s\"}", payload)); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); + return request; } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/binders/BindGenerateKeyForClientToJsonPayload.java b/apis/chef/src/main/java/org/jclouds/chef/binders/BindGenerateKeyForClientToJsonPayload.java index 537fddfbec..586a451501 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/binders/BindGenerateKeyForClientToJsonPayload.java +++ b/apis/chef/src/main/java/org/jclouds/chef/binders/BindGenerateKeyForClientToJsonPayload.java @@ -34,10 +34,11 @@ import org.jclouds.rest.binders.BindToStringPayload; public class BindGenerateKeyForClientToJsonPayload extends BindToStringPayload { @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}", payload)); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); + return request; } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/binders/BindIsCompletedToJsonPayload.java b/apis/chef/src/main/java/org/jclouds/chef/binders/BindIsCompletedToJsonPayload.java index c3e66a8f0b..579074c85f 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/binders/BindIsCompletedToJsonPayload.java +++ b/apis/chef/src/main/java/org/jclouds/chef/binders/BindIsCompletedToJsonPayload.java @@ -34,9 +34,10 @@ import org.jclouds.rest.binders.BindToStringPayload; public class BindIsCompletedToJsonPayload extends BindToStringPayload { @Override - public void bindToRequest(HttpRequest request, Object value) { + public HttpRequest bindToRequest( HttpRequest request, Object value ) { super.bindToRequest(request, String.format("{\"is_completed\":\"%s\"}", value)); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); + return request; } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/binders/BindNameToJsonPayload.java b/apis/chef/src/main/java/org/jclouds/chef/binders/BindNameToJsonPayload.java index f4eceffdb6..b51da26066 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/binders/BindNameToJsonPayload.java +++ b/apis/chef/src/main/java/org/jclouds/chef/binders/BindNameToJsonPayload.java @@ -34,9 +34,10 @@ import org.jclouds.rest.binders.BindToStringPayload; public class BindNameToJsonPayload extends BindToStringPayload { @Override - public void bindToRequest(HttpRequest request, Object payload) { + public HttpRequest bindToRequest( HttpRequest request, Object payload ) { super.bindToRequest(request, String.format("{\"name\":\"%s\"}", payload)); request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_JSON); + return request; } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/filters/SignedHeaderAuth.java b/apis/chef/src/main/java/org/jclouds/chef/filters/SignedHeaderAuth.java index 50180f3153..e3fcd27a09 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/filters/SignedHeaderAuth.java +++ b/apis/chef/src/main/java/org/jclouds/chef/filters/SignedHeaderAuth.java @@ -20,10 +20,14 @@ package org.jclouds.chef.filters; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; import static org.jclouds.Constants.PROPERTY_IDENTITY; import java.security.PrivateKey; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.NoSuchElementException; import javax.annotation.Resource; @@ -32,6 +36,11 @@ import javax.inject.Named; import javax.inject.Provider; 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.crypto.Crypto; import org.jclouds.crypto.CryptoStreams; @@ -41,6 +50,7 @@ import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequestFilter; import org.jclouds.http.HttpUtils; import org.jclouds.http.internal.SignatureWire; +import org.jclouds.http.utils.ModifyRequest; import org.jclouds.io.InputSuppliers; import org.jclouds.io.Payload; import org.jclouds.io.Payloads; @@ -92,30 +102,35 @@ public class SignedHeaderAuth implements HttpRequestFilter { this.utils = utils; } - public void filter(HttpRequest request) throws HttpException { + public HttpRequest filter( HttpRequest request ) throws HttpException { String contentHash = hashBody(request.getPayload()); - request.getHeaders().replaceValues("X-Ops-Content-Hash", Collections.singletonList(contentHash)); + Multimap headers = ArrayListMultimap.create(); + headers.put( "X-Ops-Content-Hash", contentHash ); String timestamp = timeStampProvider.get(); String toSign = createStringToSign(request.getMethod(), hashPath(request.getEndpoint().getPath()), contentHash, timestamp); - request.getHeaders().replaceValues("X-Ops-Userid", Collections.singletonList(userId)); - request.getHeaders().replaceValues("X-Ops-Sign", Collections.singletonList(SIGNING_DESCRIPTION)); - calculateAndReplaceAuthorizationHeaders(request, toSign); - request.getHeaders().replaceValues("X-Ops-Timestamp", Collections.singletonList(timestamp)); - utils.logRequest(signatureLog, request, "<<"); + headers.put("X-Ops-Userid", userId); + headers.put( "X-Ops-Sign", SIGNING_DESCRIPTION ); + request = calculateAndReplaceAuthorizationHeaders( request, toSign ); + headers.put( "X-Ops-Timestamp", timestamp ); + utils.logRequest( signatureLog, request, "<<" ); + + return ModifyRequest.putHeaders(request, headers); } @VisibleForTesting - void calculateAndReplaceAuthorizationHeaders(HttpRequest request, String toSign) throws HttpException { + HttpRequest calculateAndReplaceAuthorizationHeaders( HttpRequest request, String toSign ) throws HttpException { String signature = sign(toSign); if (signatureWire.enabled()) signatureWire.input(Utils.toInputStream(signature)); String[] signatureLines = Iterables.toArray(Splitter.fixedLength(60).split(signature), String.class); + + Multimap headers = ArrayListMultimap.create(); for (int i = 0; i < signatureLines.length; i++) { - request.getHeaders().replaceValues("X-Ops-Authorization-" + (i + 1), - Collections.singletonList(signatureLines[i])); + headers.put("X-Ops-Authorization-" + (i + 1), signatureLines[i]); } + return ModifyRequest.putHeaders( request, headers ); } public String createStringToSign(String request, String hashedPath, String contentHash, String timestamp) { diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/TagToBootScript.java b/apis/chef/src/main/java/org/jclouds/chef/functions/TagToBootScript.java index c2cd1e0f82..04f628706a 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/functions/TagToBootScript.java +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/TagToBootScript.java @@ -40,7 +40,7 @@ import org.jclouds.chef.domain.Client; import org.jclouds.crypto.Pems; import org.jclouds.io.Payload; 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.Statement; diff --git a/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefClientErrorRetryHandler.java b/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefClientErrorRetryHandler.java index b4b6967fc0..7ae64519ca 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefClientErrorRetryHandler.java +++ b/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefClientErrorRetryHandler.java @@ -57,8 +57,8 @@ public class ChefClientErrorRetryHandler implements HttpRetryHandler { public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) { if (command.getFailureCount() > retryCountLimit) return false; - if (response.getStatusCode() == 400 && command.getRequest().getMethod().equals("PUT") - && command.getRequest().getEndpoint().getPath().indexOf("sandboxes") != -1) { + if (response.getStatusCode() == 400 && command.getCurrentRequest().getMethod().equals("PUT") + && command.getCurrentRequest().getEndpoint().getPath().indexOf("sandboxes") != -1) { if (response.getPayload() != null) { String error = new String(closeClientButKeepContentStream(response)); if (error != null && error.indexOf("was not uploaded") != -1) { diff --git a/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefErrorHandler.java b/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefErrorHandler.java index b2f06b53ed..1fcec46c58 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefErrorHandler.java +++ b/apis/chef/src/main/java/org/jclouds/chef/handlers/ChefErrorHandler.java @@ -55,7 +55,7 @@ public class ChefErrorHandler implements HttpErrorHandler { String message = errorParser.apply(response); Exception exception = new HttpResponseException(command, response, message); try { - message = message != null ? message : String.format("%s -> %s", command.getRequest() + message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest() .getRequestLine(), response.getStatusLine()); switch (response.getStatusCode()) { case 401: @@ -63,7 +63,7 @@ public class ChefErrorHandler implements HttpErrorHandler { exception = new AuthorizationException(message, exception); break; case 404: - if (!command.getRequest().getMethod().equals("DELETE")) { + if (!command.getCurrentRequest().getMethod().equals("DELETE")) { exception = new ResourceNotFoundException(message, exception); } break; diff --git a/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java b/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java index dde90f1325..8acf9da024 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java +++ b/apis/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java @@ -20,7 +20,9 @@ package org.jclouds.chef.internal; import java.net.URI; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; @@ -34,7 +36,7 @@ import org.jclouds.lifecycle.Closer; import org.jclouds.rest.Utils; import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.rest.annotations.Identity; -import org.jclouds.rest.annotations.Provider; +import org.jclouds.location.Provider; import org.jclouds.rest.internal.RestContextImpl; import com.google.inject.Injector; @@ -51,7 +53,7 @@ public class ChefContextImpl extends RestContextImpl credentialStore, Utils utils, Injector injector, TypeLiteral syncApi, TypeLiteral asyncApi, @Provider URI endpoint, @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; } diff --git a/apis/chef/src/test/java/org/jclouds/chef/filters/SignedHeaderAuthTest.java b/apis/chef/src/test/java/org/jclouds/chef/filters/SignedHeaderAuthTest.java index 9f5fb6c8d5..80f75772d2 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/filters/SignedHeaderAuthTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/filters/SignedHeaderAuthTest.java @@ -140,7 +140,7 @@ public class SignedHeaderAuthTest { expected_string_to_sign); 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 headersWithoutContentLength = LinkedHashMultimap.create(request.getHeaders()); headersWithoutContentLength.removeAll(HttpHeaders.CONTENT_LENGTH); assertEquals(headersWithoutContentLength.values(), EXPECTED_SIGN_RESULT.values()); @@ -152,7 +152,7 @@ public class SignedHeaderAuthTest { URI host = URI.create("http://localhost/" + PATH); HttpRequest request = new HttpRequest(HttpMethod.DELETE, host); - signing_obj.filter(request); + request = signing_obj.filter(request); Multimap headersWithoutContentLength = LinkedHashMultimap.create(request.getHeaders()); assertEquals(headersWithoutContentLength.entries(), EXPECTED_SIGN_RESULT_EMPTY.entries()); } diff --git a/apis/chef/src/test/java/org/jclouds/chef/handlers/ChefClientErrorRetryHandlerTest.java b/apis/chef/src/test/java/org/jclouds/chef/handlers/ChefClientErrorRetryHandlerTest.java index 1d448240a5..2feb8f573d 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/handlers/ChefClientErrorRetryHandlerTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/handlers/ChefClientErrorRetryHandlerTest.java @@ -103,7 +103,7 @@ public class ChefClientErrorRetryHandlerTest { .newStringPayload("{\"error\":[\"Cannot update sandbox bfd68d4052f44053b2e593a33b5e1cd5: checksum 9b7c23369f4b576451216c39f214af6c was not uploaded\"]}")); expect(command.getFailureCount()).andReturn(0); - expect(command.getRequest()).andReturn(request).atLeastOnce(); + expect(command.getCurrentRequest()).andReturn(request).atLeastOnce(); expect(retry.shouldRetryRequest(command, response)).andReturn(true); replay(retry);