INT-1206 the "url" attribute is now required on http:outbound-gateway

This commit is contained in:
Mark Fisher
2010-06-24 22:21:33 +00:00
parent 4f991b613f
commit 1363b2699e
7 changed files with 31 additions and 162 deletions

View File

@@ -16,9 +16,7 @@
package org.springframework.integration.http;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -47,7 +45,7 @@ import org.springframework.web.client.RestTemplate;
*/
public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMessageHandler {
private final String defaultUri;
private final String uri;
private volatile HttpMethod defaultHttpMethod = HttpMethod.POST;
@@ -61,30 +59,18 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
/**
* Create an adapter that has no default URI. Any Message sent to this handler will be
* required to contain a valid value for the {@link HttpHeaders#REQUEST_URL} header.
* Create a handler that will send requests to the provided URI.
*/
public HttpRequestExecutingMessageHandler() {
this((String) null);
public HttpRequestExecutingMessageHandler(URI uri) {
this(uri.toString());
}
/**
* Create an HttpOutboundEndpoint that will send requests to the provided
* URI by default. If a Message contains a valid value for the
* {@link HttpHeaders#REQUEST_URL} header, that will take precedence.
* Create a handler that will send requests to the provided URI.
*/
public HttpRequestExecutingMessageHandler(URI defaultUri) {
this(defaultUri.toString());
}
/**
* Create an HttpOutboundEndpoint that will send requests to the provided
* URI by default. If a Message contains a valid value for the
* {@link HttpHeaders#REQUEST_URL} header, that will take precedence.
*/
public HttpRequestExecutingMessageHandler(String defaultUri) {
public HttpRequestExecutingMessageHandler(String uri) {
this.restTemplate.getMessageConverters().add(0, new SerializingHttpMessageConverter());
this.defaultUri = defaultUri;
this.uri = uri;
}
@@ -150,9 +136,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
String uri = null;
try {
uri = this.resolveUri(requestMessage);
HttpMethod httpMethod = this.resolveHttpMethod(requestMessage);
// TODO: allow a boolean flag for treating Map as queryParams vs. uriVariables?
Map<String, ?> uriVariables = this.determineUriVariables(requestMessage);
@@ -160,7 +144,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
if (!isWritableRequestMethod(httpMethod) && httpRequest.getBody() != null) {
httpRequest = new HttpEntity<Object>(null, httpRequest.getHeaders());
}
ResponseEntity<?> httpResponse = this.restTemplate.exchange(uri, httpMethod, httpRequest, this.expectedResponseType, uriVariables);
ResponseEntity<?> httpResponse = this.restTemplate.exchange(this.uri, httpMethod, httpRequest, this.expectedResponseType, uriVariables);
if (this.expectReply) {
Object responseBody = httpResponse.getBody();
MessageBuilder<?> replyBuilder = (responseBody instanceof Message<?>) ?
@@ -173,7 +157,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
throw e;
}
catch (Exception e) {
throw new MessageHandlingException(requestMessage, "HTTP request execution failed for URI [" + uri + "]", e);
throw new MessageHandlingException(requestMessage, "HTTP request execution failed for URI [" + this.uri + "]", e);
}
}
@@ -184,32 +168,6 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
}
}
/**
* Resolve the request URL for the given Message. This implementation
* returns the value associated with the {@link HttpHeaders#REQUEST_URL}
* key if available in the Message's headers. Otherwise, it falls back to
* the default URI as provided to the constructor of this handler instance.
* @throws MalformedURLException if an error occurs while constructing the URL
*/
private String resolveUri(Message<?> message) throws MalformedURLException {
Object urlHeader = message.getHeaders().get(HttpHeaders.REQUEST_URL);
if (urlHeader == null) {
Assert.notNull(this.defaultUri,
"No request URL header available in request Message, and no default has been provided.");
return this.defaultUri;
}
if (urlHeader instanceof URL) {
return ((URL) urlHeader).toString();
}
if (urlHeader instanceof URI) {
return ((URI) urlHeader).toString();
}
if (urlHeader instanceof String) {
return (String) urlHeader;
}
throw new IllegalArgumentException("Target URL in Message header must be a URL, URI, or String.");
}
private HttpMethod resolveHttpMethod(Message<?> requestMessage) {
HttpMethod httpMethod = null;
Object methodFromMessage = requestMessage.getHeaders().get(HttpHeaders.REQUEST_METHOD);

View File

@@ -22,7 +22,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractConsumerEndpointParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.util.StringUtils;
/**
* Parser for the 'outbound-gateway' element of the http namespace.
@@ -43,44 +42,16 @@ public class HttpOutboundGatewayParser extends AbstractConsumerEndpointParser {
protected BeanDefinitionBuilder parseHandler(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
PACKAGE_PATH + ".HttpRequestExecutingMessageHandler");
String defaultUrl = element.getAttribute("default-url");
if (StringUtils.hasText(defaultUrl)) {
builder.addConstructorArgValue(defaultUrl);
}
String charset = element.getAttribute("charset");
String extractPayload = element.getAttribute("extract-request-payload");
String requestMapperRef = element.getAttribute("request-mapper");
if (StringUtils.hasText(requestMapperRef)) {
if (StringUtils.hasText(charset)) {
this.requestMapperConflictError("charset", parserContext, element);
return null;
}
if (StringUtils.hasText(extractPayload)) {
this.requestMapperConflictError("extract-request-payload", parserContext, element);
return null;
}
builder.addPropertyReference("requestMapper", requestMapperRef);
}
else {
BeanDefinitionBuilder mapperBuilder = BeanDefinitionBuilder.genericBeanDefinition(
PACKAGE_PATH + ".DefaultOutboundRequestMapper");
if (StringUtils.hasText(charset)) {
mapperBuilder.addPropertyValue("charset", charset);
}
if (StringUtils.hasText(extractPayload)) {
mapperBuilder.addPropertyValue("extractPayload", extractPayload);
}
builder.addPropertyValue("requestMapper", mapperBuilder.getBeanDefinition());
}
builder.addConstructorArgValue(element.getAttribute("url"));
BeanDefinitionBuilder mapperBuilder = BeanDefinitionBuilder.genericBeanDefinition(
PACKAGE_PATH + ".DefaultOutboundRequestMapper");
IntegrationNamespaceUtils.setValueIfAttributeDefined(mapperBuilder, element, "charset");
IntegrationNamespaceUtils.setValueIfAttributeDefined(mapperBuilder, element, "extract-request-payload", "extractPayload");
builder.addPropertyValue("requestMapper", mapperBuilder.getBeanDefinition());
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "request-timeout", "sendTimeout");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "request-factory");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel", "outputChannel");
return builder;
}
private void requestMapperConflictError(String nameForGateway, ParserContext parserContext, Element element) {
parserContext.getReaderContext().error("The '" + nameForGateway + "' and 'request-mapper' are mutually exclusive. " +
"When providing an OutboundRequestMapper, set any corresponding property on the mapper directly.", element);
}
}

View File

@@ -158,7 +158,7 @@
</xsd:annotation>
<xsd:complexContent>
<xsd:extension base="gatewayType">
<xsd:attribute name="default-url" type="xsd:string">
<xsd:attribute name="url" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
URL to be used as a fallback for any request Message does not contain the request URL Message header.
@@ -167,15 +167,6 @@
</xsd:attribute>
<xsd:attribute name="extract-request-payload" type="xsd:string"/>
<xsd:attribute name="charset" type="xsd:string"/>
<xsd:attribute name="request-mapper" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.integration.http.OutboundRequestMapper"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="request-factory" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>

View File

@@ -7,6 +7,6 @@
http://www.springframework.org/schema/integration/http
http://www.springframework.org/schema/integration/http/spring-integration-http.xsd">
<http:outbound-gateway request-channel="testChannel" auto-startup="false"/>
<http:outbound-gateway url="http://localhost/test1" request-channel="testChannel" auto-startup="false"/>
</beans>

View File

@@ -68,7 +68,7 @@ public class HttpOutboundChannelAdapterParserTests {
assertTrue(mapper instanceof DefaultOutboundRequestMapper);
assertTrue(requestFactory instanceof SimpleClientHttpRequestFactory);
DirectFieldAccessor mapperAccessor = new DirectFieldAccessor(mapper);
assertEquals("http://localhost/test1", handlerAccessor.getPropertyValue("defaultUri"));
assertEquals("http://localhost/test1", handlerAccessor.getPropertyValue("uri"));
assertEquals("UTF-8", mapperAccessor.getPropertyValue("charset"));
assertEquals(true, mapperAccessor.getPropertyValue("extractPayload"));
}
@@ -92,7 +92,7 @@ public class HttpOutboundChannelAdapterParserTests {
Object requestFactoryBean = this.applicationContext.getBean("testRequestFactory");
assertEquals(requestFactoryBean, requestFactory);
DirectFieldAccessor mapperAccessor = new DirectFieldAccessor(mapper);
assertEquals("http://localhost/test2", handlerAccessor.getPropertyValue("defaultUri"));
assertEquals("http://localhost/test2", handlerAccessor.getPropertyValue("uri"));
assertEquals("UTF-8", mapperAccessor.getPropertyValue("charset"));
assertEquals(false, mapperAccessor.getPropertyValue("extractPayload"));
}

View File

@@ -12,36 +12,23 @@
<si:channel id="requests"/>
<outbound-gateway id="minimalConfig" request-channel="requests"/>
<outbound-gateway id="minimalConfig" url="http://localhost/test1" request-channel="requests"/>
<si:channel id="replies">
<si:queue/>
</si:channel>
<outbound-gateway id="fullConfigWithMapper"
<outbound-gateway id="fullConfig"
url="http://localhost/test2"
request-channel="requests"
default-url="http://localhost/test1"
request-mapper="testMapper"
request-factory="testRequestFactory"
request-timeout="1234"
extract-request-payload="false"
reply-channel="replies"
charset="UTF-8"
order="77"
auto-startup="false"/>
<outbound-gateway id="fullConfigWithoutMapper"
request-channel="requests"
default-url="http://localhost/test2"
extract-request-payload="false"
charset="UTF-8"
request-factory="testRequestFactory"
request-timeout="1234"
reply-channel="replies"/>
<beans:bean id="testMapper" class="org.springframework.integration.http.DefaultOutboundRequestMapper">
<beans:property name="charset" value="UTF-8"/>
<beans:property name="extractPayload" value="false"/>
</beans:bean>
<beans:bean id="testRequestFactory" class="org.springframework.http.client.SimpleClientHttpRequestFactory"/>
</beans:beans>

View File

@@ -18,7 +18,6 @@ package org.springframework.integration.http.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -49,11 +48,8 @@ public class HttpOutboundGatewayParserTests {
@Autowired @Qualifier("minimalConfig")
private AbstractEndpoint minimalConfigEndpoint;
@Autowired @Qualifier("fullConfigWithMapper")
private AbstractEndpoint fullConfigWithMapperEndpoint;
@Autowired @Qualifier("fullConfigWithoutMapper")
private AbstractEndpoint fullConfigWithoutMapperEndpoint;
@Autowired @Qualifier("fullConfig")
private AbstractEndpoint fullConfigEndpoint;
@Autowired
private ApplicationContext applicationContext;
@@ -75,20 +71,18 @@ public class HttpOutboundGatewayParserTests {
templateAccessor.getPropertyValue("requestFactory");
assertTrue(mapper instanceof DefaultOutboundRequestMapper);
assertTrue(requestFactory instanceof SimpleClientHttpRequestFactory);
Object mapperBean = this.applicationContext.getBean("testMapper");
assertNotSame(mapperBean, mapper);
DirectFieldAccessor mapperAccessor = new DirectFieldAccessor(mapper);
assertNull(handlerAccessor.getPropertyValue("defaultUri"));
assertEquals("http://localhost/test1", handlerAccessor.getPropertyValue("uri"));
assertEquals("UTF-8", mapperAccessor.getPropertyValue("charset"));
assertEquals(true, mapperAccessor.getPropertyValue("extractPayload"));
}
@Test
public void fullConfigWithMapper() throws Exception {
DirectFieldAccessor endpointAccessor = new DirectFieldAccessor(this.fullConfigWithMapperEndpoint);
public void fullConfig() throws Exception {
DirectFieldAccessor endpointAccessor = new DirectFieldAccessor(this.fullConfigEndpoint);
HttpRequestExecutingMessageHandler handler = (HttpRequestExecutingMessageHandler) endpointAccessor.getPropertyValue("handler");
MessageChannel requestChannel = (MessageChannel) new DirectFieldAccessor(
this.fullConfigWithMapperEndpoint).getPropertyValue("inputChannel");
this.fullConfigEndpoint).getPropertyValue("inputChannel");
assertEquals(this.applicationContext.getBean("requests"), requestChannel);
DirectFieldAccessor handlerAccessor = new DirectFieldAccessor(handler);
assertEquals(77, handlerAccessor.getPropertyValue("order"));
@@ -102,40 +96,8 @@ public class HttpOutboundGatewayParserTests {
templateAccessor.getPropertyValue("requestFactory");
assertTrue(mapper instanceof DefaultOutboundRequestMapper);
assertTrue(requestFactory instanceof SimpleClientHttpRequestFactory);
Object mapperBean = this.applicationContext.getBean("testMapper");
assertEquals(mapperBean, mapper);
DirectFieldAccessor mapperAccessor = new DirectFieldAccessor(mapper);
assertEquals("http://localhost/test1", handlerAccessor.getPropertyValue("defaultUri"));
assertEquals("UTF-8", mapperAccessor.getPropertyValue("charset"));
assertEquals(false, mapperAccessor.getPropertyValue("extractPayload"));
Object requestFactoryBean = this.applicationContext.getBean("testRequestFactory");
assertEquals(requestFactoryBean, requestFactory);
Object sendTimeout = new DirectFieldAccessor(
handlerAccessor.getPropertyValue("channelTemplate")).getPropertyValue("sendTimeout");
assertEquals(new Long("1234"), sendTimeout);
}
@Test
public void fullConfigWithoutMapper() throws Exception {
HttpRequestExecutingMessageHandler handler = (HttpRequestExecutingMessageHandler) new DirectFieldAccessor(
this.fullConfigWithoutMapperEndpoint).getPropertyValue("handler");
MessageChannel requestChannel = (MessageChannel) new DirectFieldAccessor(
this.fullConfigWithoutMapperEndpoint).getPropertyValue("inputChannel");
assertEquals(this.applicationContext.getBean("requests"), requestChannel);
DirectFieldAccessor handlerAccessor = new DirectFieldAccessor(handler);
Object replyChannel = handlerAccessor.getPropertyValue("outputChannel");
assertNotNull(replyChannel);
assertEquals(this.applicationContext.getBean("replies"), replyChannel);
OutboundRequestMapper mapper = (OutboundRequestMapper) handlerAccessor.getPropertyValue("requestMapper");
DirectFieldAccessor templateAccessor = new DirectFieldAccessor(handlerAccessor.getPropertyValue("restTemplate"));
ClientHttpRequestFactory requestFactory = (ClientHttpRequestFactory)
templateAccessor.getPropertyValue("requestFactory");
assertTrue(mapper instanceof DefaultOutboundRequestMapper);
assertTrue(requestFactory instanceof SimpleClientHttpRequestFactory);
Object mapperBean = this.applicationContext.getBean("testMapper");
assertNotSame(mapperBean, mapper);
DirectFieldAccessor mapperAccessor = new DirectFieldAccessor(mapper);
assertEquals("http://localhost/test2", handlerAccessor.getPropertyValue("defaultUri"));
assertEquals("http://localhost/test2", handlerAccessor.getPropertyValue("uri"));
assertEquals("UTF-8", mapperAccessor.getPropertyValue("charset"));
assertEquals(false, mapperAccessor.getPropertyValue("extractPayload"));
Object requestFactoryBean = this.applicationContext.getBean("testRequestFactory");