Repository: camel Updated Branches: refs/heads/master 9c878faf3 -> 9e09dd422
CAMEL-11111: correctly copy responseâs headers and body to exception Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9e09dd42 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9e09dd42 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9e09dd42 Branch: refs/heads/master Commit: 9e09dd4223491215e7b389d1741539b71605a833 Parents: 9c878fa Author: Scott Cranton <sc...@cranton.com> Authored: Sun Apr 9 11:26:32 2017 -0400 Committer: Scott Cranton <sc...@cranton.com> Committed: Sun Apr 9 11:26:32 2017 -0400 ---------------------------------------------------------------------- .../undertow/UndertowClientCallback.java | 22 +++++++------ ...rtowProducerThrowExceptionOnFailureTest.java | 33 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/9e09dd42/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowClientCallback.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowClientCallback.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowClientCallback.java index 6b48203..8f312e8 100644 --- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowClientCallback.java +++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowClientCallback.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.concurrent.BlockingDeque; import java.util.concurrent.LinkedBlockingDeque; import java.util.function.Consumer; +import java.util.stream.Collectors; import io.undertow.client.ClientCallback; import io.undertow.client.ClientConnection; @@ -218,15 +219,17 @@ class UndertowClientCallback implements ClientCallback<ClientConnection> { // operation failed so populate exception to throw final String uri = endpoint.getHttpURI().toString(); final String statusText = clientExchange.getResponse().getStatus(); - HeaderMap headerMap = clientExchange.getResponse().getResponseHeaders(); - Map<String, String> headers = new HashMap<>(); - for (HttpString headerName : headerMap.getHeaderNames()) { - Object value = headerMap.get(headerName); - if (value != null) { - headers.put(headerName.toString(), value.toString()); - } - } - final Exception cause = new HttpOperationFailedException(uri, code, statusText, null, headers, result.getBody(String.class)); + + // Convert Message headers (Map<String, Object>) to Map<String, String> as expected by HttpOperationsFailedException + // using Message versus clientExchange as its header values have extra formatting + final Map<String, String> headers = result.getHeaders().entrySet() + .stream() + .collect(Collectors.toMap(Map.Entry::getKey, (entry) -> entry.getValue().toString())); + + // Since result (Message) isn't associated with an Exchange yet, you can not use result.getBody(String.class) + final String bodyText = ExchangeHelper.convertToType(exchange, String.class, result.getBody()); + + final Exception cause = new HttpOperationFailedException(uri, code, statusText, null, headers, bodyText); if (ExchangeHelper.isOutCapable(exchange)) { exchange.setOut(result); @@ -236,7 +239,6 @@ class UndertowClientCallback implements ClientCallback<ClientConnection> { // make sure to fail with HttpOperationFailedException hasFailedWith(cause); - } else { // we end Camel exchange here finish(result); http://git-wip-us.apache.org/repos/asf/camel/blob/9e09dd42/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerThrowExceptionOnFailureTest.java ---------------------------------------------------------------------- diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerThrowExceptionOnFailureTest.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerThrowExceptionOnFailureTest.java index b281699..9675080 100644 --- a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerThrowExceptionOnFailureTest.java +++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/UndertowProducerThrowExceptionOnFailureTest.java @@ -16,10 +16,12 @@ */ package org.apache.camel.component.undertow; +import com.fasterxml.jackson.core.JsonParseException; import org.apache.camel.CamelExecutionException; import org.apache.camel.Exchange; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.http.common.HttpOperationFailedException; +import org.apache.camel.model.rest.RestBindingMode; import org.junit.Test; public class UndertowProducerThrowExceptionOnFailureTest extends BaseUndertowTest { @@ -46,11 +48,42 @@ public class UndertowProducerThrowExceptionOnFailureTest extends BaseUndertowTes } } + @Test + public void testFailWithException2() throws Exception { + try { + String out = fluentTemplate().to("undertow:http://localhost:{{port2}}/test/fail?throwExceptionOnFailure=true") + .withHeader(Exchange.HTTP_METHOD, "PUT") + .withBody("This is not JSON format") + .request(String.class); + + fail("Should throw an exception"); + } catch (CamelExecutionException e) { + HttpOperationFailedException httpException = (HttpOperationFailedException) e.getCause(); + + assertEquals(400, httpException.getStatusCode()); + assertEquals("text/plain", httpException.getResponseHeaders().get(Exchange.CONTENT_TYPE)); + assertEquals("Invalid json data", httpException.getResponseBody()); + } + } + @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { + restConfiguration() + .component("undertow").port(getPort2()) + .bindingMode(RestBindingMode.json); + + onException(JsonParseException.class) + .handled(true) + .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(400)) + .setHeader(Exchange.CONTENT_TYPE, constant("text/plain")) + .setBody().constant("Invalid json data"); + + rest("/test") + .put("/fail").to("mock:test"); + from("undertow:http://localhost:{{port}}/fail") .setHeader(Exchange.HTTP_RESPONSE_CODE).constant(404) .transform(constant("Fail"));