diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/DefaultParameterMapper.java b/spring-integration-http/src/main/java/org/springframework/integration/http/DefaultParameterMapper.java new file mode 100644 index 0000000000..af75d25103 --- /dev/null +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/DefaultParameterMapper.java @@ -0,0 +1,76 @@ +/* + * Copyright 2002-2008 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. + * 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.springframework.integration.http; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.expression.Expression; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.integration.core.Message; + +/** + * @author Dave Syer + * @since 2.0 + * + */ +public class DefaultParameterMapper implements ParameterMapper { + + private static Log logger = LogFactory.getLog(DefaultParameterMapper.class); + + private SpelExpressionParser parser = new SpelExpressionParser(); + + private Map dynamicParameterExpressions = new HashMap(); + + /** + * A map of parameter name to SpEL expressions on the message. + * + * @param dynamicParameterExpressions the dynamic parameter expressions to set + */ + public void setDynamicParameterExpressions(Map dynamicParameterExpressions) { + this.dynamicParameterExpressions.clear(); + for (String key : dynamicParameterExpressions.keySet()) { + this.dynamicParameterExpressions.put(key, parser.parseExpression(dynamicParameterExpressions.get(key))); + } + } + + public Map fromMessage(Message requestMessage) { + + Map params = new HashMap(); + for (String key : dynamicParameterExpressions.keySet()) { + Object value = dynamicParameterExpressions.get(key).getValue(requestMessage); + params.put(key, value); + } + + if (requestMessage.getPayload() instanceof Map) { + Map payloadMap = (Map) requestMessage.getPayload(); + for (Object key : payloadMap.keySet()) { + if (key instanceof String) { + params.put((String) key, payloadMap.get(key).toString()); + } + else if (logger.isDebugEnabled()) { + logger.debug("ignoring Map value for non-String key: " + key); + } + } + } + + return params; + + } + +} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutingMessageHandler.java b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutingMessageHandler.java index 5962f9d225..5de1727428 100755 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutingMessageHandler.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/HttpRequestExecutingMessageHandler.java @@ -17,7 +17,6 @@ package org.springframework.integration.http; import java.net.URI; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -57,6 +56,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe private final RestTemplate restTemplate = new RestTemplate(); + private ParameterMapper parameterMapper = new DefaultParameterMapper(); /** * Create a handler that will send requests to the provided URI. @@ -142,12 +142,21 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe public void setRequestFactory(ClientHttpRequestFactory requestFactory) { this.restTemplate.setRequestFactory(requestFactory); } + + /** + * Set the {@link ParameterMapper} for creating URI parameters from the outbound message. + * + * @param parameterMapper the parameter mapper to set + */ + public void setParameterMapper(ParameterMapper parameterMapper) { + this.parameterMapper = parameterMapper; + } @Override protected Object handleRequestMessage(Message requestMessage) { try { // TODO: allow a boolean flag for treating Map as queryParams vs. uriVariables? - Map uriVariables = this.determineUriVariables(requestMessage); + Map uriVariables = this.parameterMapper.fromMessage(requestMessage); HttpEntity httpRequest = this.requestMapper.fromMessage(requestMessage); ResponseEntity httpResponse = this.restTemplate.exchange(this.uri, this.httpMethod, httpRequest, this.expectedResponseType, uriVariables); if (this.expectReply) { @@ -171,20 +180,4 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe } } - private Map determineUriVariables(Message requestMessage) { - Map uriVariables = new HashMap(); - if (requestMessage.getPayload() instanceof Map) { - Map payloadMap = (Map) requestMessage.getPayload(); - for (Object key : payloadMap.keySet()) { - if (key instanceof String) { - uriVariables.put((String) key, payloadMap.get(key).toString()); - } - else if (logger.isDebugEnabled()) { - logger.debug("ignoring Map value for non-String key: " + key); - } - } - } - return uriVariables; - } - } diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/ParameterMapper.java b/spring-integration-http/src/main/java/org/springframework/integration/http/ParameterMapper.java new file mode 100644 index 0000000000..be43abe166 --- /dev/null +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/ParameterMapper.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2008 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. + * 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.springframework.integration.http; + +import java.util.Map; + +import org.springframework.integration.core.Message; + +/** + * @author Dave Syer + * + * @since 2.0 + * + */ +public interface ParameterMapper { + + /** + * @param requestMessage + * @return a map of parameters + */ + Map fromMessage(Message requestMessage); + +} diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParser.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParser.java index 162e65e3be..50ea8eb8e4 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParser.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParser.java @@ -42,6 +42,7 @@ public class HttpOutboundChannelAdapterParser extends AbstractOutboundChannelAda builder.addConstructorArgValue(element.getAttribute("url")); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "http-method"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "message-converters"); + IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "parameter-mapper"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "extract-payload"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expected-response-type"); diff --git a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundGatewayParser.java b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundGatewayParser.java index cd64b59cac..243d711d24 100644 --- a/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundGatewayParser.java +++ b/spring-integration-http/src/main/java/org/springframework/integration/http/config/HttpOutboundGatewayParser.java @@ -45,6 +45,7 @@ public class HttpOutboundGatewayParser extends AbstractConsumerEndpointParser { builder.addConstructorArgValue(element.getAttribute("url")); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "http-method"); IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "message-converters"); + IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "parameter-mapper"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "charset"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "extract-request-payload", "extractPayload"); IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "expected-response-type"); diff --git a/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-2.0.xsd b/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-2.0.xsd index a0a31d61e0..7b2b82de0b 100644 --- a/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-2.0.xsd +++ b/spring-integration-http/src/main/resources/org/springframework/integration/http/config/spring-integration-http-2.0.xsd @@ -112,6 +112,15 @@ ]]> + + + + + + + + + @@ -195,6 +204,15 @@ + + + + + + + + + diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/mapper/DataBindingInboundRequestMapperTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/DataBindingInboundRequestMapperTests.java similarity index 98% rename from spring-integration-http/src/test/java/org/springframework/integration/http/mapper/DataBindingInboundRequestMapperTests.java rename to spring-integration-http/src/test/java/org/springframework/integration/http/DataBindingInboundRequestMapperTests.java index f1b661505e..8c671f3a14 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/mapper/DataBindingInboundRequestMapperTests.java +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/DataBindingInboundRequestMapperTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.integration.http.mapper; +package org.springframework.integration.http; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/DefaultParameterMapperTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/DefaultParameterMapperTests.java new file mode 100644 index 0000000000..8dcc352f39 --- /dev/null +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/DefaultParameterMapperTests.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002-2008 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. + * 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.springframework.integration.http; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; +import java.util.Map; + +import org.junit.Test; +import org.springframework.integration.message.GenericMessage; + +/** + * @author Dave Syer + * @since 2.0 + * + */ +public class DefaultParameterMapperTests { + + @Test + public void testFromMessage() throws Exception { + DefaultParameterMapper mapper = new DefaultParameterMapper(); + Map params = mapper.fromMessage(new GenericMessage(Collections.singletonMap("foo", "bar"))); + assertEquals(1, params.size()); + assertEquals("bar", params.get("foo")); + } + + @Test + public void testFromMessageWithExpressions() throws Exception { + DefaultParameterMapper mapper = new DefaultParameterMapper(); + mapper.setDynamicParameterExpressions(Collections.singletonMap("foo", "payload")); + Map params = mapper.fromMessage(new GenericMessage("bar")); + assertEquals(1, params.size()); + assertEquals("bar", params.get("foo")); + } + +} diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests-context.xml b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests-context.xml index b502a07062..1a3fea50c8 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests-context.xml +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests-context.xml @@ -16,6 +16,7 @@ + + diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests.java index 03319f1e16..c87e6a18af 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests.java +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundChannelAdapterParserTests.java @@ -34,6 +34,7 @@ import org.springframework.integration.endpoint.AbstractEndpoint; import org.springframework.integration.http.DefaultOutboundRequestMapper; import org.springframework.integration.http.HttpRequestExecutingMessageHandler; import org.springframework.integration.http.OutboundRequestMapper; +import org.springframework.integration.http.ParameterMapper; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -53,6 +54,9 @@ public class HttpOutboundChannelAdapterParserTests { @Autowired private ApplicationContext applicationContext; + @Autowired + private ParameterMapper parameterMapper; + @Test public void minimalConfig() { @@ -101,6 +105,7 @@ public class HttpOutboundChannelAdapterParserTests { assertEquals(HttpMethod.GET, handlerAccessor.getPropertyValue("httpMethod")); assertEquals("UTF-8", mapperAccessor.getPropertyValue("charset")); assertEquals(false, mapperAccessor.getPropertyValue("extractPayload")); + assertEquals(parameterMapper, handlerAccessor.getPropertyValue("parameterMapper")); } } diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests-context.xml b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests-context.xml index 5ee93c298d..9da4697e7e 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests-context.xml +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests-context.xml @@ -22,6 +22,7 @@ + + diff --git a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java index fa29828f3f..dc721eaf09 100644 --- a/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java +++ b/spring-integration-http/src/test/java/org/springframework/integration/http/config/HttpOutboundGatewayParserTests.java @@ -36,6 +36,7 @@ import org.springframework.integration.endpoint.AbstractEndpoint; import org.springframework.integration.http.DefaultOutboundRequestMapper; import org.springframework.integration.http.HttpRequestExecutingMessageHandler; import org.springframework.integration.http.OutboundRequestMapper; +import org.springframework.integration.http.ParameterMapper; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -55,6 +56,8 @@ public class HttpOutboundGatewayParserTests { @Autowired private ApplicationContext applicationContext; + @Autowired + private ParameterMapper parameterMapper; @Test public void minimalConfig() { @@ -111,6 +114,7 @@ public class HttpOutboundGatewayParserTests { Object sendTimeout = new DirectFieldAccessor( handlerAccessor.getPropertyValue("channelTemplate")).getPropertyValue("sendTimeout"); assertEquals(new Long("1234"), sendTimeout); + assertEquals(parameterMapper, handlerAccessor.getPropertyValue("parameterMapper")); } }