From 3369d3f9b1752b1d7e3b9655f27f2cb924a2cc39 Mon Sep 17 00:00:00 2001 From: Wallace Wadge Date: Mon, 10 Jun 2013 11:19:08 +0200 Subject: [PATCH] INT-3054 URI Variable Mapping Improvements Permit missing URI vars in HTTP outbound gateway Do not attempt to evaluate uri variables that are not in the URL The http gateway might not know what uri variables it might obtain in the URI. This patch makes sure that only the uri variables defined in the uri are parsed (the rest are ignored) --- .../HttpRequestExecutingMessageHandler.java | 16 +++++++-- .../outbound/UriVariableExpressionTests.java | 35 ++++++++++++++++++- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/outbound/HttpRequestExecutingMessageHandler.java b/spring-integration-http/src/main/java/org/springframework/integration/http/outbound/HttpRequestExecutingMessageHandler.java index 9de441aaae..2aedef7229 100755 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/outbound/HttpRequestExecutingMessageHandler.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/outbound/HttpRequestExecutingMessageHandler.java @@ -63,6 +63,7 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.web.util.UriTemplate; /** * A {@link MessageHandler} implementation that executes HTTP requests by delegating @@ -79,6 +80,7 @@ import org.springframework.web.util.UriComponentsBuilder; * @author Gary Russell * @author Gunnar Hillert * @author Artem Bilan + * @author Wallace Wadge * @since 2.0 */ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMessageHandler { @@ -337,11 +339,19 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe protected Object handleRequestMessage(Message requestMessage) { String uri = this.uriExpression.getValue(this.evaluationContext, requestMessage, String.class); Assert.notNull(uri, "URI Expression evaluation cannot result in null"); + List uriVariableNames = new UriTemplate(uri).getVariableNames(); + + if (logger.isWarnEnabled() && this.uriVariableExpressions.size() != uriVariableNames.size()){ + logger.warn("The number of URI variables expecting resolution in the provided uri do not match those in the provided variables"); + } try { Map uriVariables = new HashMap(); - for (Map.Entry entry : this.uriVariableExpressions.entrySet()) { - Object value = entry.getValue().getValue(this.evaluationContext, requestMessage, String.class); - uriVariables.put(entry.getKey(), value); + for (String var : uriVariableNames) { + Expression exp = this.uriVariableExpressions.get(var); + if (exp != null){ + Object value = exp.getValue(this.evaluationContext, requestMessage, String.class); + uriVariables.put(var, value); + } } HttpMethod httpMethod = this.determineHttpMethod(requestMessage); diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/outbound/UriVariableExpressionTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/outbound/UriVariableExpressionTests.java index b974837838..976d6695ab 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/outbound/UriVariableExpressionTests.java +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/outbound/UriVariableExpressionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2013 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,10 +21,13 @@ import static org.junit.Assert.assertEquals; import java.io.IOException; import java.net.URI; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; +import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpRequest; @@ -35,6 +38,7 @@ import org.springframework.integration.message.GenericMessage; /** * @author Dave Syer * @author Mark Fisher + * @author Wallace Wadge * @since 2.0 */ public class UriVariableExpressionTests { @@ -65,4 +69,33 @@ public class UriVariableExpressionTests { assertEquals("http://test/bar", uriHolder.get().toString()); } + /** Test for INT-3054: Do not break if there are extra uri variables defined in the http outbound gateway. */ + @Test + public void testFromMessageWithSuperfluousExpressionsInt3054() throws Exception { + final AtomicReference uriHolder = new AtomicReference(); + HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler("http://test/{foo}"); + SpelExpressionParser parser = new SpelExpressionParser(); + Map multipleExpressions = new HashMap(); + multipleExpressions.put("foo", parser.parseExpression("payload")); + multipleExpressions.put("extra-to-be-ignored", parser.parseExpression("headers.extra")); + handler.setUriVariableExpressions(multipleExpressions); + handler.setRequestFactory(new SimpleClientHttpRequestFactory() { + @Override + public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { + uriHolder.set(uri); + throw new RuntimeException("intentional"); + } + }); + Message message = new GenericMessage("bar"); + Exception exception = null; + try { + handler.handleMessage(message); + } + catch (Exception e) { + exception = e; + } + assertEquals("intentional", exception.getCause().getMessage()); + assertEquals("http://test/bar", uriHolder.get().toString()); + } + }