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:
@@ -77,10 +77,10 @@ abstract class AbstractStandardMessageHandlerFactoryBean extends AbstractSimpleM
|
||||
if (this.targetObject != null) {
|
||||
Assert.state(this.expression == null,
|
||||
"The 'targetObject' and 'expression' properties are mutually exclusive.");
|
||||
boolean targetIsDirectReplyProducingHandler = this.extractTypeIfPossible(targetObject,
|
||||
AbstractReplyProducingMessageHandler.class) != null
|
||||
&& this.canBeUsedDirect(
|
||||
(AbstractReplyProducingMessageHandler) targetObject) // give subclasses a say
|
||||
AbstractReplyProducingMessageHandler actualHandler = this.extractTypeIfPossible(targetObject,
|
||||
AbstractReplyProducingMessageHandler.class);
|
||||
boolean targetIsDirectReplyProducingHandler = actualHandler != null
|
||||
&& this.canBeUsedDirect(actualHandler) // give subclasses a say
|
||||
&& this.methodIsHandleMessageOrEmpty(this.targetMethodName);
|
||||
if (this.targetObject instanceof MessageProcessor<?>) {
|
||||
handler = this.createMessageProcessingHandler((MessageProcessor<?>) this.targetObject);
|
||||
@@ -89,9 +89,9 @@ abstract class AbstractStandardMessageHandlerFactoryBean extends AbstractSimpleM
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Wiring handler (" + beanName + ") directly into endpoint");
|
||||
}
|
||||
this.checkReuse(actualHandler);
|
||||
this.postProcessReplyProducer(actualHandler);
|
||||
handler = (MessageHandler) targetObject;
|
||||
this.checkReuse((AbstractReplyProducingMessageHandler) handler);
|
||||
this.postProcessReplyProducer((AbstractReplyProducingMessageHandler) handler);
|
||||
}
|
||||
else {
|
||||
handler = this.createMethodInvokingHandler(this.targetObject, this.targetMethodName);
|
||||
@@ -120,7 +120,7 @@ abstract class AbstractStandardMessageHandlerFactoryBean extends AbstractSimpleM
|
||||
}
|
||||
|
||||
private void checkReuse(AbstractReplyProducingMessageHandler replyHandler) {
|
||||
Assert.isTrue(!referencedReplyProducers.contains(targetObject),
|
||||
Assert.isTrue(!referencedReplyProducers.contains(replyHandler),
|
||||
"An AbstractReplyProducingMessageHandler may only be referenced once (" +
|
||||
replyHandler.getComponentName() + ") - use scope=\"prototype\"");
|
||||
referencedReplyProducers.add(replyHandler);
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.beans.factory.support.ManagedMap;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.integration.gateway.GatewayProxyFactoryBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -43,7 +44,7 @@ import org.springframework.util.xml.DomUtils;
|
||||
public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
private static String[] referenceAttributes = new String[] {
|
||||
"default-request-channel", "default-reply-channel", "error-channel", "message-mapper", "async-executor"
|
||||
"default-request-channel", "default-reply-channel", "error-channel", "message-mapper", "async-executor", "mapper"
|
||||
};
|
||||
|
||||
private static String[] innerAttributes = new String[] {
|
||||
@@ -93,9 +94,16 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, attributeName);
|
||||
}
|
||||
|
||||
boolean hasMapper = StringUtils.hasText(element.getAttribute("mapper"));
|
||||
boolean hasDefaultPayloadExpression = StringUtils.hasText(element.getAttribute("default-payload-expression"));
|
||||
Assert.state(hasMapper ? !hasDefaultPayloadExpression : true, "'default-payload-expression' is not allowed when a 'mapper' is provided");
|
||||
|
||||
List<Element> invocationHeaders = DomUtils.getChildElementsByTagName(element, "default-header");
|
||||
if (!CollectionUtils.isEmpty(invocationHeaders)
|
||||
|| StringUtils.hasText(element.getAttribute("default-payload-expression"))) {
|
||||
boolean hasDefaultHeaders = !CollectionUtils.isEmpty(invocationHeaders);
|
||||
|
||||
Assert.state(hasMapper ? !hasDefaultHeaders : true, "default-header elements are not allowed when a 'mapper' is provided");
|
||||
|
||||
if (hasDefaultHeaders || hasDefaultPayloadExpression) {
|
||||
BeanDefinitionBuilder methodMetadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.integration.gateway.GatewayMethodMetadata");
|
||||
this.setMethodInvocationHeaders(methodMetadataBuilder, invocationHeaders);
|
||||
@@ -118,8 +126,11 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
methodMetadataBuilder.addPropertyValue("requestTimeout", methodElement.getAttribute("request-timeout"));
|
||||
methodMetadataBuilder.addPropertyValue("replyTimeout", methodElement.getAttribute("reply-timeout"));
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(methodMetadataBuilder, methodElement, "payload-expression");
|
||||
Assert.state(hasMapper ? !StringUtils.hasText(element.getAttribute("payload-expression")) : true,
|
||||
"'payload-expression' is not allowed when a 'mapper' is provided");
|
||||
invocationHeaders = DomUtils.getChildElementsByTagName(methodElement, "header");
|
||||
if (!CollectionUtils.isEmpty(invocationHeaders)) {
|
||||
Assert.state(!hasMapper, "header elements are not allowed when a 'mapper' is provided");
|
||||
this.setMethodInvocationHeaders(methodMetadataBuilder, invocationHeaders);
|
||||
}
|
||||
methodMetadataMap.put(methodName, methodMetadataBuilder.getBeanDefinition());
|
||||
|
||||
@@ -20,12 +20,14 @@ import java.util.List;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.config.TypedStringValue;
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
@@ -33,14 +35,13 @@ import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.config.ExpressionFactoryBean;
|
||||
import org.springframework.integration.config.SpelFunctionFactoryBean;
|
||||
import org.springframework.integration.endpoint.AbstractPollingEndpoint;
|
||||
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
|
||||
import org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
@@ -462,6 +463,7 @@ public abstract class IntegrationNamespaceUtils {
|
||||
}
|
||||
return expressionDef;
|
||||
}
|
||||
|
||||
public static void registerSpelFunctionBean(BeanDefinitionRegistry registry, String functionId, String className,
|
||||
String methodSignature) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SpelFunctionFactoryBean.class)
|
||||
@@ -469,6 +471,7 @@ public abstract class IntegrationNamespaceUtils {
|
||||
.addConstructorArgValue(methodSignature);
|
||||
registry.registerBeanDefinition(functionId, builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
public static BeanDefinition createExpressionDefIfAttributeDefined(String expressionElementName, Element element) {
|
||||
|
||||
Assert.hasText(expressionElementName, "'expressionElementName' must no be empty");
|
||||
|
||||
@@ -98,8 +98,7 @@ public class MessageFilter extends AbstractReplyProducingPostProcessingMessageHa
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onInit() {
|
||||
super.onInit();
|
||||
protected void doInit() {
|
||||
if (this.selector instanceof AbstractMessageProcessingSelector) {
|
||||
((AbstractMessageProcessingSelector) this.selector).setConversionService(this.getConversionService());
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.springframework.integration.annotation.Headers;
|
||||
import org.springframework.integration.annotation.Payload;
|
||||
import org.springframework.integration.expression.ExpressionUtils;
|
||||
import org.springframework.integration.mapping.InboundMessageMapper;
|
||||
import org.springframework.integration.mapping.MessageMappingException;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -85,6 +86,8 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
|
||||
private final List<MethodParameter> parameterList;
|
||||
|
||||
private final MethodArgsMessageMapper argsMapper;
|
||||
|
||||
private volatile Expression payloadExpression;
|
||||
|
||||
private final Map<String, Expression> parameterPayloadExpressions = new HashMap<String, Expression>();
|
||||
@@ -93,23 +96,28 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
|
||||
private volatile BeanFactory beanFactory;
|
||||
|
||||
|
||||
public GatewayMethodInboundMessageMapper(Method method) {
|
||||
this(method, null);
|
||||
}
|
||||
|
||||
public GatewayMethodInboundMessageMapper(Method method, Map<String, Expression> headerExpressions) {
|
||||
this(method, headerExpressions, null);
|
||||
this(method, headerExpressions, null, null);
|
||||
}
|
||||
|
||||
public GatewayMethodInboundMessageMapper(Method method, Map<String, Expression> headerExpressions,
|
||||
Map<String, Expression> globalHeaderExpressions) {
|
||||
Map<String, Expression> globalHeaderExpressions, MethodArgsMessageMapper mapper) {
|
||||
Assert.notNull(method, "method must not be null");
|
||||
this.method = method;
|
||||
this.headerExpressions = headerExpressions;
|
||||
this.globalHeaderExpressions = globalHeaderExpressions;
|
||||
this.parameterList = getMethodParameterList(method);
|
||||
this.payloadExpression = parsePayloadExpression(method);
|
||||
if (mapper == null) {
|
||||
this.argsMapper = new DefaultMethodArgsMessageMapper();
|
||||
}
|
||||
else {
|
||||
this.argsMapper = mapper;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -135,85 +143,17 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
}
|
||||
|
||||
private Message<?> mapArgumentsToMessage(Object[] arguments) {
|
||||
Object messageOrPayload = null;
|
||||
boolean foundPayloadAnnotation = false;
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
EvaluationContext methodInvocationEvaluationContext = createMethodInvocationEvaluationContext(arguments);
|
||||
if (this.payloadExpression != null) {
|
||||
messageOrPayload = this.payloadExpression.getValue(methodInvocationEvaluationContext);
|
||||
try {
|
||||
return this.argsMapper.toMessage(new MethodArgsHolder(this.method, arguments));
|
||||
}
|
||||
for (int i = 0; i < this.parameterList.size(); i++) {
|
||||
Object argumentValue = arguments[i];
|
||||
MethodParameter methodParameter = this.parameterList.get(i);
|
||||
Annotation annotation = this.findMappingAnnotation(methodParameter.getParameterAnnotations());
|
||||
if (annotation != null) {
|
||||
if (annotation.annotationType().equals(Payload.class)) {
|
||||
if (messageOrPayload != null) {
|
||||
this.throwExceptionForMultipleMessageOrPayloadParameters(methodParameter);
|
||||
}
|
||||
String expression = ((Payload) annotation).value();
|
||||
if (!StringUtils.hasText(expression)) {
|
||||
messageOrPayload = argumentValue;
|
||||
}
|
||||
else {
|
||||
messageOrPayload = this.evaluatePayloadExpression(expression, argumentValue);
|
||||
}
|
||||
foundPayloadAnnotation = true;
|
||||
}
|
||||
else if (annotation.annotationType().equals(Header.class)) {
|
||||
Header headerAnnotation = (Header) annotation;
|
||||
String headerName = this.determineHeaderName(headerAnnotation, methodParameter);
|
||||
if (headerAnnotation.required() && argumentValue == null) {
|
||||
throw new IllegalArgumentException("Received null argument value for required header: '" + headerName + "'");
|
||||
}
|
||||
headers.put(headerName, argumentValue);
|
||||
}
|
||||
else if (annotation.annotationType().equals(Headers.class)) {
|
||||
if (argumentValue != null) {
|
||||
if (!(argumentValue instanceof Map)) {
|
||||
throw new IllegalArgumentException("@Headers annotation is only valid for Map-typed parameters");
|
||||
}
|
||||
for (Object key : ((Map<?, ?>) argumentValue).keySet()) {
|
||||
Assert.isInstanceOf(String.class, key, "Invalid header name [" + key +
|
||||
"], name type must be String.");
|
||||
Object value = ((Map<?, ?>) argumentValue).get(key);
|
||||
headers.put((String) key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (e instanceof MessagingException) {
|
||||
throw (MessagingException) e;
|
||||
}
|
||||
else if (messageOrPayload == null) {
|
||||
messageOrPayload = argumentValue;
|
||||
}
|
||||
else if (Map.class.isAssignableFrom(methodParameter.getParameterType())) {
|
||||
if (messageOrPayload instanceof Map && !foundPayloadAnnotation) {
|
||||
if (payloadExpression == null){
|
||||
throw new MessagingException("Ambiguous method parameters; found more than one " +
|
||||
"Map-typed parameter and neither one contains a @Payload annotation");
|
||||
}
|
||||
}
|
||||
this.copyHeaders((Map<?, ?>) argumentValue, headers);
|
||||
}
|
||||
else if (this.payloadExpression == null) {
|
||||
this.throwExceptionForMultipleMessageOrPayloadParameters(methodParameter);
|
||||
else {
|
||||
throw new MessageMappingException("Failed to map arguments", e);
|
||||
}
|
||||
}
|
||||
Assert.isTrue(messageOrPayload != null, "unable to determine a Message or payload parameter on method [" + method + "]");
|
||||
MessageBuilder<?> builder = (messageOrPayload instanceof Message)
|
||||
? MessageBuilder.fromMessage((Message<?>) messageOrPayload)
|
||||
: MessageBuilder.withPayload(messageOrPayload);
|
||||
builder.copyHeadersIfAbsent(headers);
|
||||
// Explicit headers in XML override any @Header annotations...
|
||||
if (!CollectionUtils.isEmpty(this.headerExpressions)) {
|
||||
Map<String, Object> evaluatedHeaders = evaluateHeaders(methodInvocationEvaluationContext, this.headerExpressions);
|
||||
builder.copyHeaders(evaluatedHeaders);
|
||||
}
|
||||
// ...whereas global (default) headers do not...
|
||||
if (!CollectionUtils.isEmpty(this.globalHeaderExpressions)) {
|
||||
Map<String, Object> evaluatedHeaders = evaluateHeaders(methodInvocationEvaluationContext, this.globalHeaderExpressions);
|
||||
builder.copyHeadersIfAbsent(evaluatedHeaders);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Map<String, Object> evaluateHeaders(EvaluationContext methodInvocationEvaluationContext, Map<String, Expression> headerExpressions) {
|
||||
@@ -318,4 +258,94 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
return expression;
|
||||
}
|
||||
|
||||
public class DefaultMethodArgsMessageMapper implements MethodArgsMessageMapper {
|
||||
|
||||
@Override
|
||||
public Message<?> toMessage(MethodArgsHolder holder) throws Exception {
|
||||
Object messageOrPayload = null;
|
||||
boolean foundPayloadAnnotation = false;
|
||||
Object[] arguments = holder.getArgs();
|
||||
EvaluationContext methodInvocationEvaluationContext = createMethodInvocationEvaluationContext(arguments);
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
if (GatewayMethodInboundMessageMapper.this.payloadExpression != null) {
|
||||
messageOrPayload = GatewayMethodInboundMessageMapper.this.payloadExpression.getValue(methodInvocationEvaluationContext);
|
||||
}
|
||||
for (int i = 0; i < GatewayMethodInboundMessageMapper.this.parameterList.size(); i++) {
|
||||
Object argumentValue = arguments[i];
|
||||
MethodParameter methodParameter = GatewayMethodInboundMessageMapper.this.parameterList.get(i);
|
||||
Annotation annotation = GatewayMethodInboundMessageMapper.this.findMappingAnnotation(methodParameter.getParameterAnnotations());
|
||||
if (annotation != null) {
|
||||
if (annotation.annotationType().equals(Payload.class)) {
|
||||
if (messageOrPayload != null) {
|
||||
GatewayMethodInboundMessageMapper.this.throwExceptionForMultipleMessageOrPayloadParameters(methodParameter);
|
||||
}
|
||||
String expression = ((Payload) annotation).value();
|
||||
if (!StringUtils.hasText(expression)) {
|
||||
messageOrPayload = argumentValue;
|
||||
}
|
||||
else {
|
||||
messageOrPayload = GatewayMethodInboundMessageMapper.this.evaluatePayloadExpression(expression, argumentValue);
|
||||
}
|
||||
foundPayloadAnnotation = true;
|
||||
}
|
||||
else if (annotation.annotationType().equals(Header.class)) {
|
||||
Header headerAnnotation = (Header) annotation;
|
||||
String headerName = GatewayMethodInboundMessageMapper.this.determineHeaderName(headerAnnotation, methodParameter);
|
||||
if (headerAnnotation.required() && argumentValue == null) {
|
||||
throw new IllegalArgumentException("Received null argument value for required header: '" + headerName + "'");
|
||||
}
|
||||
headers.put(headerName, argumentValue);
|
||||
}
|
||||
else if (annotation.annotationType().equals(Headers.class)) {
|
||||
if (argumentValue != null) {
|
||||
if (!(argumentValue instanceof Map)) {
|
||||
throw new IllegalArgumentException("@Headers annotation is only valid for Map-typed parameters");
|
||||
}
|
||||
for (Object key : ((Map<?, ?>) argumentValue).keySet()) {
|
||||
Assert.isInstanceOf(String.class, key, "Invalid header name [" + key +
|
||||
"], name type must be String.");
|
||||
Object value = ((Map<?, ?>) argumentValue).get(key);
|
||||
headers.put((String) key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (messageOrPayload == null) {
|
||||
messageOrPayload = argumentValue;
|
||||
}
|
||||
else if (Map.class.isAssignableFrom(methodParameter.getParameterType())) {
|
||||
if (messageOrPayload instanceof Map && !foundPayloadAnnotation) {
|
||||
if (payloadExpression == null){
|
||||
throw new MessagingException("Ambiguous method parameters; found more than one " +
|
||||
"Map-typed parameter and neither one contains a @Payload annotation");
|
||||
}
|
||||
}
|
||||
GatewayMethodInboundMessageMapper.this.copyHeaders((Map<?, ?>) argumentValue, headers);
|
||||
}
|
||||
else if (GatewayMethodInboundMessageMapper.this.payloadExpression == null) {
|
||||
GatewayMethodInboundMessageMapper.this.throwExceptionForMultipleMessageOrPayloadParameters(methodParameter);
|
||||
}
|
||||
}
|
||||
Assert.isTrue(messageOrPayload != null, "unable to determine a Message or payload parameter on method [" + method + "]");
|
||||
MessageBuilder<?> builder = (messageOrPayload instanceof Message)
|
||||
? MessageBuilder.fromMessage((Message<?>) messageOrPayload)
|
||||
: MessageBuilder.withPayload(messageOrPayload);
|
||||
builder.copyHeadersIfAbsent(headers);
|
||||
// Explicit headers in XML override any @Header annotations...
|
||||
if (!CollectionUtils.isEmpty(GatewayMethodInboundMessageMapper.this.headerExpressions)) {
|
||||
Map<String, Object> evaluatedHeaders = evaluateHeaders(methodInvocationEvaluationContext,
|
||||
GatewayMethodInboundMessageMapper.this.headerExpressions);
|
||||
builder.copyHeaders(evaluatedHeaders);
|
||||
}
|
||||
// ...whereas global (default) headers do not...
|
||||
if (!CollectionUtils.isEmpty(GatewayMethodInboundMessageMapper.this.globalHeaderExpressions)) {
|
||||
Map<String, Object> evaluatedHeaders = evaluateHeaders(methodInvocationEvaluationContext,
|
||||
GatewayMethodInboundMessageMapper.this.globalHeaderExpressions);
|
||||
builder.copyHeadersIfAbsent(evaluatedHeaders);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -105,6 +105,8 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
|
||||
private volatile GatewayMethodMetadata globalMethodMetadata;
|
||||
|
||||
private volatile MethodArgsMessageMapper argsMapper;
|
||||
|
||||
/**
|
||||
* Create a Factory whose service interface type can be configured by setter injection.
|
||||
* If none is set, it will fall back to the default service interface type,
|
||||
@@ -214,6 +216,15 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
this.beanClassLoader = beanClassLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a custom {@link MethodArgsMessageMapper} to map from a {@link MethodArgsHolder}
|
||||
* to a {@link Message}.
|
||||
* @param mapper the mapper.
|
||||
*/
|
||||
public final void setMapper(MethodArgsMessageMapper mapper) {
|
||||
this.argsMapper = mapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
synchronized (this.initializationMonitor) {
|
||||
@@ -395,7 +406,8 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
}
|
||||
}
|
||||
GatewayMethodInboundMessageMapper messageMapper = new GatewayMethodInboundMessageMapper(method, headerExpressions,
|
||||
this.globalMethodMetadata != null ? this.globalMethodMetadata.getHeaderExpressions() : null);
|
||||
this.globalMethodMetadata != null ? this.globalMethodMetadata.getHeaderExpressions() : null,
|
||||
this.argsMapper);
|
||||
if (StringUtils.hasText(payloadExpression)) {
|
||||
messageMapper.setPayloadExpression(payloadExpression);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.gateway;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Simple wrapper class containing a {@link Method} and an object
|
||||
* array containing the arguments for an invocation of that method.
|
||||
* For example used by a {@link MethodArgsMessageMapper} with this generic
|
||||
* type to provide custom argument mapping when creating a message
|
||||
* in a {@code GatewayProxyFactoryBean}.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 3.0
|
||||
*
|
||||
*/
|
||||
public final class MethodArgsHolder {
|
||||
|
||||
private final Method method;
|
||||
|
||||
private final Object[] args;
|
||||
|
||||
public MethodArgsHolder(Method method, Object[] args) {
|
||||
this.method = method;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public final Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public final Object[] getArgs() {
|
||||
return args;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.gateway;
|
||||
|
||||
import org.springframework.integration.mapping.InboundMessageMapper;
|
||||
|
||||
/**
|
||||
* Implementations of this interface are {@link InboundMessageMapper}s
|
||||
* that map a {@link MethodArgsHolder} to a {@link org.springframework.integration.Message}.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 3.0
|
||||
*
|
||||
*/
|
||||
public interface MethodArgsMessageMapper extends InboundMessageMapper<MethodArgsHolder> {
|
||||
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package org.springframework.integration.handler;
|
||||
import java.util.List;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.integration.core.MessageProducer;
|
||||
@@ -114,7 +115,7 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
protected final void onInit() {
|
||||
if (this.getBeanFactory() != null) {
|
||||
this.messagingTemplate.setBeanFactory(getBeanFactory());
|
||||
}
|
||||
@@ -125,6 +126,10 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
}
|
||||
this.advisedRequestHandler = (RequestHandler) proxyFactory.getProxy(this.beanClassLoader);
|
||||
}
|
||||
this.doInit();
|
||||
}
|
||||
|
||||
protected void doInit() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -196,8 +196,7 @@ public class DelayHandler extends AbstractReplyProducingMessageHandler implement
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
super.onInit();
|
||||
protected void doInit() {
|
||||
if (this.messageStore == null) {
|
||||
this.messageStore = new SimpleMessageStore();
|
||||
}
|
||||
|
||||
@@ -55,8 +55,7 @@ public class ServiceActivatingHandler extends AbstractReplyProducingMessageHandl
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onInit() {
|
||||
super.onInit();
|
||||
protected void doInit() {
|
||||
if (processor instanceof AbstractMessageProcessor) {
|
||||
((AbstractMessageProcessor<?>) this.processor).setConversionService(this.getConversionService());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.
|
||||
@@ -28,7 +28,7 @@ import org.springframework.util.Assert;
|
||||
/**
|
||||
* Base class for Message Splitter implementations that delegate to a
|
||||
* {@link MessageProcessor} instance.
|
||||
*
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -43,8 +43,7 @@ abstract class AbstractMessageProcessingSplitter extends AbstractMessageSplitter
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInit() {
|
||||
super.onInit();
|
||||
protected void doInit() {
|
||||
ConversionService conversionService = this.getConversionService();
|
||||
if (conversionService != null && this.messageProcessor instanceof AbstractMessageProcessor) {
|
||||
((AbstractMessageProcessor<?>) this.messageProcessor).setConversionService(conversionService);
|
||||
|
||||
@@ -194,8 +194,7 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler implem
|
||||
* the requestChannel is set.
|
||||
*/
|
||||
@Override
|
||||
public void onInit() {
|
||||
super.onInit();
|
||||
protected void doInit() {
|
||||
if (this.replyChannel != null) {
|
||||
Assert.notNull(this.requestChannel, "If the replyChannel is set, then the requestChannel must not be null");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.
|
||||
@@ -54,8 +54,7 @@ public class MessageTransformingHandler extends AbstractReplyProducingMessageHan
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
super.onInit();
|
||||
protected void doInit() {
|
||||
if (this.getBeanFactory() != null && this.transformer instanceof BeanFactoryAware) {
|
||||
((BeanFactoryAware) this.transformer).setBeanFactory(this.getBeanFactory());
|
||||
}
|
||||
|
||||
@@ -717,6 +717,22 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="mapper" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
An MethodArgsMessageMapper to map the method arguments to a Message. When this
|
||||
is provided, no payload-expressions or headers are allowed; the custom mapper is
|
||||
responsible for creating the message.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.gateway.MethodArgsMessageMapper" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
@@ -23,16 +23,20 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.core.MessageHandler;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.handler.DelayHandler;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
@@ -48,6 +52,7 @@ import org.springframework.transaction.interceptor.TransactionInterceptor;
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @author Gunnar Hillert
|
||||
* @author Gary Russell
|
||||
* @since 1.0.3
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -100,7 +105,7 @@ public class DelayerParserTests {
|
||||
}
|
||||
|
||||
@Test //INT-2649
|
||||
public void transactionalSubElement() {
|
||||
public void transactionalSubElement() throws Exception {
|
||||
Object endpoint = context.getBean("delayerWithTransactional");
|
||||
DelayHandler delayHandler = TestUtils.getPropertyValue(endpoint, "handler", DelayHandler.class);
|
||||
List<?> adviceChain = TestUtils.getPropertyValue(delayHandler, "delayedAdviceChain", List.class);
|
||||
@@ -109,7 +114,8 @@ public class DelayerParserTests {
|
||||
assertTrue(advice instanceof TransactionInterceptor);
|
||||
TransactionAttributeSource transactionAttributeSource = ((TransactionInterceptor) advice).getTransactionAttributeSource();
|
||||
assertTrue(transactionAttributeSource instanceof MatchAlwaysTransactionAttributeSource);
|
||||
TransactionDefinition definition = transactionAttributeSource.getTransactionAttribute(null, null);
|
||||
Method method = MessageHandler.class.getMethod("handleMessage", Message.class);
|
||||
TransactionDefinition definition = transactionAttributeSource.getTransactionAttribute(method, null);
|
||||
assertEquals(TransactionDefinition.PROPAGATION_REQUIRED, definition.getPropagationBehavior());
|
||||
assertEquals(TransactionDefinition.ISOLATION_DEFAULT, definition.getIsolationLevel());
|
||||
assertEquals(TransactionDefinition.TIMEOUT_DEFAULT, definition.getTimeout());
|
||||
|
||||
@@ -39,12 +39,12 @@ import org.springframework.util.StopWatch;
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gunnar Hillert
|
||||
* @author Gary Russell
|
||||
*/
|
||||
|
||||
public class MessageIdGenerationTests {
|
||||
|
||||
@Test
|
||||
public void testCustomIdGenerationWithParentRegistrar() throws Exception{
|
||||
public void testCustomIdGenerationWithParentRegistrar() throws Exception {
|
||||
ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context-withGenerator.xml", this.getClass());
|
||||
ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext(new String[]{"MessageIdGenerationTests-context.xml"}, this.getClass(), parent);
|
||||
|
||||
@@ -58,7 +58,7 @@ public class MessageIdGenerationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomIdGenerationWithParentChileIndependentCreation() throws Exception{
|
||||
public void testCustomIdGenerationWithParentChildIndependentCreation() throws Exception {
|
||||
ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context-withGenerator.xml", this.getClass());
|
||||
GenericXmlApplicationContext child = new GenericXmlApplicationContext();
|
||||
child.load("classpath:/org/springframework/integration/core/MessageIdGenerationTests-context.xml");
|
||||
@@ -89,7 +89,7 @@ public class MessageIdGenerationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomIdGenerationWithChildRegistrar() throws Exception{
|
||||
public void testCustomIdGenerationWithChildRegistrar() throws Exception {
|
||||
ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context.xml", this.getClass());
|
||||
ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext(new String[]{"MessageIdGenerationTests-context-withGenerator.xml"}, this.getClass(), parent);
|
||||
|
||||
@@ -98,13 +98,13 @@ public class MessageIdGenerationTests {
|
||||
MessageChannel inputChannel = child.getBean("input", MessageChannel.class);
|
||||
inputChannel.send(new GenericMessage<Integer>(0));
|
||||
verify(idGenerator, atLeastOnce()).generateId();
|
||||
parent.close();
|
||||
child.close();
|
||||
parent.close();
|
||||
this.assertDestroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomIdGenerationWithChildRegistrarClosed() throws Exception{
|
||||
public void testCustomIdGenerationWithChildRegistrarClosed() throws Exception {
|
||||
ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context.xml", this.getClass());
|
||||
ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext(new String[]{"MessageIdGenerationTests-context-withGenerator.xml"}, this.getClass(), parent);
|
||||
|
||||
@@ -120,7 +120,7 @@ public class MessageIdGenerationTests {
|
||||
|
||||
// similar to the last test, but should not fail because child AC is closed before second child AC is started
|
||||
@Test
|
||||
public void testCustomIdGenerationWithParentChildIndependentCreationChildrenRegistrarsOneAtTheTime() throws Exception{
|
||||
public void testCustomIdGenerationWithParentChildIndependentCreationChildrenRegistrarsOneAtTheTime() throws Exception {
|
||||
ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context.xml", this.getClass());
|
||||
|
||||
GenericXmlApplicationContext childA = new GenericXmlApplicationContext();
|
||||
@@ -142,7 +142,7 @@ public class MessageIdGenerationTests {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void performanceTest(){
|
||||
public void performanceTest() {
|
||||
int times = 1000000;
|
||||
StopWatch watch = new StopWatch();
|
||||
watch.start();
|
||||
|
||||
@@ -20,4 +20,10 @@
|
||||
<int:channel id="requestChannelBar"/>
|
||||
<int:channel id="requestChannelBaz"/>
|
||||
|
||||
<int:gateway id="customMappedGateway"
|
||||
service-interface="org.springframework.integration.gateway.GatewayInterfaceTests.Baz"
|
||||
default-request-channel="requestChannelBaz" mapper="mapper"/>
|
||||
|
||||
<bean id="mapper" class="org.springframework.integration.gateway.GatewayInterfaceTests$BazMapper"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
@@ -238,6 +239,26 @@ public class GatewayInterfaceTests {
|
||||
new GatewayProxyFactoryBean(NotAnInterface.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithCustomMapper() {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
|
||||
final AtomicBoolean called = new AtomicBoolean();
|
||||
MessageHandler handler = new MessageHandler() {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
assertThat((String) message.getPayload(), equalTo("fizbuz"));
|
||||
called.set(true);
|
||||
}
|
||||
};
|
||||
channel.subscribe(handler);
|
||||
Baz baz = ac.getBean(Baz.class);
|
||||
baz.baz("hello");
|
||||
assertTrue(called.get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
public interface Foo {
|
||||
@Gateway(requestChannel="requestChannelFoo")
|
||||
@@ -256,4 +277,18 @@ public class GatewayInterfaceTests {
|
||||
public static class NotAnInterface {
|
||||
public void fail(String payload){}
|
||||
}
|
||||
|
||||
public interface Baz {
|
||||
|
||||
public void baz(String payload);
|
||||
}
|
||||
|
||||
public static class BazMapper implements MethodArgsMessageMapper {
|
||||
|
||||
@Override
|
||||
public Message<?> toMessage(MethodArgsHolder object) throws Exception {
|
||||
return MessageBuilder.withPayload("fizbuz").build();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.integration.annotation.Header;
|
||||
import org.springframework.integration.annotation.Headers;
|
||||
import org.springframework.integration.annotation.Payload;
|
||||
import org.springframework.integration.mapping.MessageMappingException;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
@@ -78,7 +79,7 @@ public class GatewayMethodInboundMessageMapperToMessageTests {
|
||||
assertEquals("bar", message.getHeaders().get("foo"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test(expected = MessageMappingException.class)
|
||||
public void toMessageWithPayloadAndRequiredHeaderButNullValue() throws Exception {
|
||||
Method method = TestService.class.getMethod(
|
||||
"sendPayloadAndHeader", String.class, String.class);
|
||||
@@ -134,7 +135,7 @@ public class GatewayMethodInboundMessageMapperToMessageTests {
|
||||
assertEquals("test", message.getPayload());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test(expected = MessageMappingException.class)
|
||||
public void toMessageWithPayloadAndHeadersMapWithNonStringKey() throws Exception {
|
||||
Method method = TestService.class.getMethod(
|
||||
"sendPayloadAndHeadersMap", String.class, Map.class);
|
||||
@@ -166,7 +167,7 @@ public class GatewayMethodInboundMessageMapperToMessageTests {
|
||||
assertEquals("bar", message.getHeaders().get("foo"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test(expected = MessageMappingException.class)
|
||||
public void toMessageWithMessageParameterAndRequiredHeaderButNullValue() throws Exception {
|
||||
Method method = TestService.class.getMethod("sendMessageAndHeader", Message.class, String.class);
|
||||
GatewayMethodInboundMessageMapper mapper = new GatewayMethodInboundMessageMapper(method);
|
||||
@@ -197,7 +198,7 @@ public class GatewayMethodInboundMessageMapperToMessageTests {
|
||||
assertNull(message.getHeaders().get("foo"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test(expected = MessageMappingException.class)
|
||||
public void noArgs() throws Exception {
|
||||
Method method = TestService.class.getMethod("noArgs", new Class<?>[] {});
|
||||
GatewayMethodInboundMessageMapper mapper = new GatewayMethodInboundMessageMapper(method);
|
||||
@@ -205,7 +206,7 @@ public class GatewayMethodInboundMessageMapperToMessageTests {
|
||||
mapper.toMessage(new Object[] {});
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test(expected = MessageMappingException.class)
|
||||
public void onlyHeaders() throws Exception {
|
||||
Method method = TestService.class.getMethod("onlyHeaders", String.class, String.class);
|
||||
GatewayMethodInboundMessageMapper mapper = new GatewayMethodInboundMessageMapper(method);
|
||||
|
||||
@@ -94,7 +94,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotOptimizedReplyingMessageHandler() {
|
||||
public void testOptimizedReplyingMessageHandler() {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message = MessageBuilder.withPayload("test").setReplyChannel(replyChannel).build();
|
||||
this.optimizedRefReplyingHandlerTestInputChannel.send(message);
|
||||
|
||||
@@ -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.
|
||||
@@ -24,18 +24,17 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.integration.config.ConsumerEndpointFactoryBean;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.integration.router.AbstractMappingMessageRouter;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -43,10 +42,10 @@ public class RouterWithMappingTests {
|
||||
|
||||
@Autowired
|
||||
private MessageChannel expressionRouter;
|
||||
|
||||
|
||||
@Autowired
|
||||
@Qualifier("spelRouter")
|
||||
private ConsumerEndpointFactoryBean spelRouter;
|
||||
@Qualifier("spelRouter.handler")
|
||||
private AbstractMappingMessageRouter spelRouterHandler;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel pojoRouter;
|
||||
@@ -87,8 +86,7 @@ public class RouterWithMappingTests {
|
||||
assertNull(fooChannelForExpression.receive(0));
|
||||
assertNull(barChannelForExpression.receive(0));
|
||||
// validate dynamics
|
||||
AbstractMappingMessageRouter router = (AbstractMappingMessageRouter) TestUtils.getPropertyValue(spelRouter, "handler");
|
||||
router.setChannelMapping("baz", "fooChannelForExpression");
|
||||
spelRouterHandler.setChannelMapping("baz", "fooChannelForExpression");
|
||||
expressionRouter.send(message3);
|
||||
assertNull(defaultChannelForExpression.receive(10));
|
||||
assertNotNull(fooChannelForExpression.receive(10));
|
||||
|
||||
Reference in New Issue
Block a user