Merge remote-tracking branch 'upstream/master' into 4.0.0-WIP

Conflicts:
	spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java
	spring-integration-core/src/test/java/org/springframework/integration/router/config/RouterWithMappingTests.java
	spring-integration-groovy/src/main/java/org/springframework/integration/groovy/GroovyScriptExecutingMessageProcessor.java
	spring-integration-http/src/test/java/org/springframework/integration/http/inbound/HttpRequestHandlingMessagingGatewayWithPathMappingTests.java
	spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/AbstractTxTimeoutMessageStoreTests.java
	spring-integration-jmx/src/main/java/org/springframework/integration/jmx/OperationInvokingMessageHandler.java

Resolved.
This commit is contained in:
Gary Russell
2013-10-30 23:13:27 -04:00
93 changed files with 1657 additions and 787 deletions

View File

@@ -19,10 +19,12 @@ package org.springframework.integration.http.inbound;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -65,6 +67,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;
@@ -210,8 +213,15 @@ public abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewa
/**
* Specifies a SpEL expression to evaluate in order to generate the Message payload.
* The EvaluationContext will be populated with an HttpEntity instance as the root object,
* and it may contain one or both of the <code>#pathVariables</code> and
* <code>#queryParameters</code> variables if present. Those variables' values are Maps.
* and it may contain variables:
* <ul>
* <li><code>#pathVariables</code></li>
* <li><code>#requestParams</code></li>
* <li><code>#requestAttributes</code></li>
* <li><code>#requestHeaders</code></li>
* <li><code>#matrixVariables</code></li>
* <li><code>#cookies</code>
* </ul>
*/
public void setPayloadExpression(Expression payloadExpression) {
this.payloadExpression = payloadExpression;
@@ -221,8 +231,15 @@ public abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewa
* Specifies a Map of SpEL expressions to evaluate in order to generate the Message headers.
* The keys in the map will be used as the header names. When evaluating the expression,
* the EvaluationContext will be populated with an HttpEntity instance as the root object,
* and it may contain one or both of the <code>#pathVariables</code> and
* <code>#queryParameters</code> variables if present. Those variables' values are Maps.
* and it may contain variables:
* <ul>
* <li><code>#pathVariables</code></li>
* <li><code>#requestParams</code></li>
* <li><code>#requestAttributes</code></li>
* <li><code>#requestHeaders</code></li>
* <li><code>#matrixVariables</code></li>
* <li><code>#cookies</code>
* </ul>
*/
public void setHeaderExpressions(Map<String, Expression> headerExpressions) {
this.headerExpressions = headerExpressions;
@@ -379,9 +396,22 @@ public abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewa
StandardEvaluationContext evaluationContext = this.createEvaluationContext();
evaluationContext.setRootObject(httpEntity);
evaluationContext.setVariable("requestAttributes", RequestContextHolder.currentRequestAttributes());
MultiValueMap<String, String> requestParams = this.convertParameterMap(servletRequest.getParameterMap());
evaluationContext.setVariable("requestParams", requestParams);
evaluationContext.setVariable("requestHeaders", new ServletServerHttpRequest(servletRequest).getHeaders());
Cookie[] requestCookies = servletRequest.getCookies();
if (!ObjectUtils.isEmpty(requestCookies)) {
Map<String, Cookie> cookies = new HashMap<String, Cookie>(requestCookies.length);
for (Cookie requestCookie : requestCookies) {
cookies.put(requestCookie.getName(), requestCookie);
}
evaluationContext.setVariable("cookies", cookies);
}
Map<String, String> pathVariables =
(Map<String, String>) servletRequest.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
@@ -392,6 +422,17 @@ public abstract class HttpRequestHandlingEndpointSupport extends MessagingGatewa
evaluationContext.setVariable("pathVariables", pathVariables);
}
//TODO change it to HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE after upgrade to Spring 4.0
Map<String, MultiValueMap<String, String>> matrixVariables =
(Map<String, MultiValueMap<String, String>>) servletRequest.getAttribute(HandlerMapping.class.getName() + ".matrixVariables");
if (!CollectionUtils.isEmpty(matrixVariables)) {
if (logger.isDebugEnabled()) {
logger.debug("Mapped matrix variables: " + matrixVariables);
}
evaluationContext.setVariable("matrixVariables", matrixVariables);
}
Map<String, Object> headers = this.headerMapper.toHeaders(request.getHeaders());
Object payload = null;
if (this.payloadExpression != null) {

View File

@@ -291,8 +291,7 @@ public class HttpRequestExecutingMessageHandler extends AbstractReplyProducingMe
}
@Override
public void onInit() {
super.onInit();
protected void doInit() {
this.evaluationContext = ExpressionUtils.createStandardEvaluationContext(this.getBeanFactory());
ConversionService conversionService = this.getConversionService();

View File

@@ -0,0 +1,42 @@
/*
* Copyright 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.
* 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 org.junit.After;
import org.junit.Before;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* @author Artem Bilan
* @since 3.0
*/
public abstract class AbstractHttpInboundTests {
@Before
public void setupHttpInbound() {
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(new MockHttpServletRequest()));
}
@After
public void tearDownHttpInbound() {
RequestContextHolder.resetRequestAttributes();
}
}

View File

@@ -137,6 +137,7 @@ public class HttpProxyScenarioTests {
assertEquals(ifModifiedSince, headers.get("If-Modified-Since"));
assertEquals(ifUnmodifiedSince, headers.get("If-Unmodified-Since"));
RequestContextHolder.resetRequestAttributes();
}
}

View File

@@ -18,11 +18,11 @@ package org.springframework.integration.http.config;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
@@ -36,11 +36,9 @@ import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.converter.HttpMessageConverter;
@@ -48,6 +46,7 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.PollableChannel;
import org.springframework.integration.history.MessageHistory;
import org.springframework.integration.http.AbstractHttpInboundTests;
import org.springframework.integration.http.converter.SerializingHttpMessageConverter;
import org.springframework.integration.http.inbound.HttpRequestHandlingController;
import org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway;
@@ -74,7 +73,7 @@ import org.springframework.web.servlet.HandlerMapping;
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class HttpInboundChannelAdapterParserTests {
public class HttpInboundChannelAdapterParserTests extends AbstractHttpInboundTests {
@Autowired
private PollableChannel requests;

View File

@@ -39,6 +39,7 @@ import org.springframework.messaging.Message;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.http.AbstractHttpInboundTests;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@@ -54,7 +55,7 @@ import org.springframework.web.servlet.View;
* @author Biju Kunjummen
* @since 2.0
*/
public class HttpRequestHandlingControllerTests {
public class HttpRequestHandlingControllerTests extends AbstractHttpInboundTests {
@Test
public void sendOnly() throws Exception {

View File

@@ -16,9 +16,9 @@
package org.springframework.integration.http.inbound;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import java.io.IOException;
@@ -43,6 +43,7 @@ import org.springframework.messaging.Message;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.http.AbstractHttpInboundTests;
import org.springframework.integration.http.converter.SerializingHttpMessageConverter;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.mock.web.MockHttpServletRequest;
@@ -58,7 +59,7 @@ import org.springframework.util.SerializationUtils;
* @author Biju Kunjummen
* @since 2.0
*/
public class HttpRequestHandlingMessagingGatewayTests {
public class HttpRequestHandlingMessagingGatewayTests extends AbstractHttpInboundTests {
@Test
@SuppressWarnings("unchecked")

View File

@@ -27,11 +27,12 @@ import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.http.AbstractHttpInboundTests;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessagingException;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.util.AntPathMatcher;
@@ -45,7 +46,7 @@ import org.springframework.web.servlet.HandlerMapping;
* @author Artem Bilan
* @author Biju Kunjummen
*/
public class HttpRequestHandlingMessagingGatewayWithPathMappingTests {
public class HttpRequestHandlingMessagingGatewayWithPathMappingTests extends AbstractHttpInboundTests {
private static ExpressionParser PARSER = new SpelExpressionParser();

View File

@@ -26,8 +26,16 @@
request-channel="toLowerCaseChannel"
payload-expression="#pathVariables.value">
<int-http:request-mapping headers="toLowerCase"/>
<int-http:header name="requestAttributes" expression="#requestAttributes"/>
<int-http:header name="requestParams" expression="#requestParams"/>
<int-http:header name="requestHeaders" expression="#requestHeaders"/>
<int-http:header name="matrixVariables" expression="#matrixVariables"/>
<int-http:header name="cookies" expression="#cookies"/>
</int-http:inbound-gateway>
<int:publish-subscribe-channel id="toLowerCaseChannel"/>
<int:transformer input-channel="toLowerCaseChannel" expression="payload.toLowerCase()"/>
<int-http:inbound-gateway path="#{TEST_PATH}"

View File

@@ -17,22 +17,37 @@
package org.springframework.integration.http.inbound;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.Cookie;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.MessagingException;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.http.AbstractHttpInboundTests;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
@@ -44,7 +59,7 @@ import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
//INT-2312
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class Int2312RequestMappingIntegrationTests {
public class Int2312RequestMappingIntegrationTests extends AbstractHttpInboundTests {
public static final String TEST_PATH = "/test/{value}";
@@ -53,6 +68,9 @@ public class Int2312RequestMappingIntegrationTests {
@Autowired
private HandlerMapping handlerMapping;
@Autowired
private SubscribableChannel toLowerCaseChannel;
private HandlerAdapter handlerAdapter = new HttpRequestHandlerAdapter();
@Test
@@ -77,26 +95,63 @@ public class Int2312RequestMappingIntegrationTests {
@Test
@SuppressWarnings("unchecked")
//INT-1362
public void testURIVariablesAndHeaders() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("GET");
String testRequest = "aBc";
// TODO test it after upgrade to Spring 4.0
// String testRequest = "aBc;q1=1;q2=2";
String requestURI = "/test/" + testRequest;
request.setRequestURI(requestURI);
request.setContentType("text/plain");
final Map<String, String> params = new HashMap<String, String>();
params.put("foo", "bar");
request.setParameters(params);
request.setContent("hello".getBytes());
final Cookie cookie = new Cookie("foo", "bar");
request.setCookies(cookie);
request.addHeader("toLowerCase", true);
//See org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping#handleMatch
Map<String, String> uriTemplateVariables =
new AntPathMatcher().extractUriTemplateVariables(TEST_PATH, requestURI);
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
//See org.springframework.web.servlet.FrameworkServlet#initContextHolders
final RequestAttributes attributes = new ServletRequestAttributes(request);
RequestContextHolder.setRequestAttributes(attributes);
this.toLowerCaseChannel.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
MessageHeaders headers = message.getHeaders();
assertEquals(attributes, headers.get("requestAttributes"));
Object requestParams = headers.get("requestParams");
assertNotNull(requestParams);
assertEquals(params, ((MultiValueMap<String, String>) requestParams).toSingleValueMap());
// TODO test it after upgrade to Spring 4.0
// assertEquals(matrixVariables, headers.get("matrixVariables"));
Object requestHeaders = headers.get("requestHeaders");
assertNotNull(requestParams);
assertEquals(MediaType.TEXT_PLAIN, ((HttpHeaders) requestHeaders).getContentType());
Map<String, Cookie> cookies = (Map<String, Cookie>) headers.get("cookies");
assertEquals(1, cookies.size());
Cookie foo = cookies.get("foo");
assertNotNull(foo);
assertEquals(cookie, foo);
}
});
MockHttpServletResponse response = new MockHttpServletResponse();
request.addHeader("toLowerCase", true);
Object handler = this.handlerMapping.getHandler(request).getHandler();
this.handlerAdapter.handle(request, response, handler);
final String testResponse = response.getContentAsString();
assertEquals(testRequest.toLowerCase(), testResponse);
RequestContextHolder.resetRequestAttributes();
}
@Test