INT-3402-3: Channels Late Resolution #3
JIRA: https://jira.spring.io/browse/INT-3402 * Add late resolution of channel names for the `MessagingGatewaySupport` * Implement delegate logic for internal implementations like `ContentEnricher.Gateway`
This commit is contained in:
committed by
Gary Russell
parent
1c051416ce
commit
7f74c571d4
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.integration.gateway;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.integration.core.MessagingTemplate;
|
||||
import org.springframework.integration.endpoint.AbstractEndpoint;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
@@ -33,6 +34,7 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.core.DestinationResolutionException;
|
||||
import org.springframework.messaging.support.ErrorMessage;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -53,10 +55,16 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
|
||||
private volatile MessageChannel requestChannel;
|
||||
|
||||
private volatile String requestChannelName;
|
||||
|
||||
private volatile MessageChannel replyChannel;
|
||||
|
||||
private volatile String replyChannelName;
|
||||
|
||||
private volatile MessageChannel errorChannel;
|
||||
|
||||
private volatile String errorChannelName;
|
||||
|
||||
private volatile long replyTimeout = DEFAULT_TIMEOUT;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@@ -66,7 +74,8 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
|
||||
private final MessagingTemplate messagingTemplate;
|
||||
|
||||
private final HistoryWritingMessagePostProcessor historyWritingPostProcessor = new HistoryWritingMessagePostProcessor();
|
||||
private final HistoryWritingMessagePostProcessor historyWritingPostProcessor =
|
||||
new HistoryWritingMessagePostProcessor();
|
||||
|
||||
private volatile boolean initialized;
|
||||
|
||||
@@ -86,38 +95,67 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
|
||||
/**
|
||||
* Set the request channel.
|
||||
*
|
||||
* @param requestChannel the channel to which request messages will be sent
|
||||
*/
|
||||
public void setRequestChannel(MessageChannel requestChannel) {
|
||||
this.requestChannel = requestChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the request channel name.
|
||||
* @param requestChannelName the channel bean name to which request messages will be sent
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setRequestChannelName(String requestChannelName) {
|
||||
Assert.hasText(requestChannelName, "'requestChannelName' must not be empty");
|
||||
this.requestChannelName = requestChannelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reply channel. If no reply channel is provided, this gateway will
|
||||
* always use an anonymous, temporary channel for handling replies.
|
||||
*
|
||||
* @param replyChannel the channel from which reply messages will be received
|
||||
*/
|
||||
public void setReplyChannel(MessageChannel replyChannel) {
|
||||
this.replyChannel = replyChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reply channel name. If no reply channel is provided, this gateway will
|
||||
* always use an anonymous, temporary channel for handling replies.
|
||||
* @param replyChannelName the channel bean name from which reply messages will be received
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setReplyChannelName(String replyChannelName) {
|
||||
Assert.hasText(replyChannelName, "'replyChannelName' must not be empty");
|
||||
this.replyChannelName = replyChannelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the error channel. If no error channel is provided, this gateway will
|
||||
* propagate Exceptions to the caller. To completely suppress Exceptions, provide
|
||||
* a reference to the "nullChannel" here.
|
||||
*
|
||||
* @param errorChannel The error channel.
|
||||
*/
|
||||
public void setErrorChannel(MessageChannel errorChannel) {
|
||||
this.errorChannel = errorChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the error channel name. If no error channel is provided, this gateway will
|
||||
* propagate Exceptions to the caller. To completely suppress Exceptions, provide
|
||||
* a reference to the "nullChannel" here.
|
||||
* @param errorChannelName The error channel bean name.
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setErrorChannelName(String errorChannelName) {
|
||||
Assert.hasText(errorChannelName, "'errorChannelName' must not be empty");
|
||||
this.errorChannelName = errorChannelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timeout value for sending request messages. If not
|
||||
* explicitly configured, the default is one second.
|
||||
*
|
||||
* @param requestTimeout the timeout value in milliseconds
|
||||
*/
|
||||
public void setRequestTimeout(long requestTimeout) {
|
||||
@@ -127,7 +165,6 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
/**
|
||||
* Set the timeout value for receiving reply messages. If not
|
||||
* explicitly configured, the default is one second.
|
||||
*
|
||||
* @param replyTimeout the timeout value in milliseconds
|
||||
*/
|
||||
public void setReplyTimeout(long replyTimeout) {
|
||||
@@ -138,7 +175,6 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
/**
|
||||
* Provide an {@link InboundMessageMapper} for creating request Messages
|
||||
* from any object passed in a send or sendAndReceive operation.
|
||||
*
|
||||
* @param requestMapper The request mapper.
|
||||
*/
|
||||
public void setRequestMapper(InboundMessageMapper<?> requestMapper) {
|
||||
@@ -150,7 +186,6 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
/**
|
||||
* Provide an {@link OutboundMessageMapper} for mapping to objects from
|
||||
* any reply Messages received in receive or sendAndReceive operations.
|
||||
*
|
||||
* @param replyMapper The reply mapper.
|
||||
*/
|
||||
public void setReplyMapper(OutboundMessageMapper<?> replyMapper) {
|
||||
@@ -173,6 +208,12 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
|
||||
@Override
|
||||
protected void onInit() throws Exception {
|
||||
Assert.state(!(this.requestChannelName != null && this.requestChannel != null),
|
||||
"'requestChannelName' and 'requestChannel' are mutually exclusive.");
|
||||
Assert.state(!(this.replyChannelName != null && this.replyChannel != null),
|
||||
"'replyChannelName' and 'replyChannel' are mutually exclusive.");
|
||||
Assert.state(!(this.errorChannelName != null && this.errorChannel != null),
|
||||
"'errorChannelName' and 'errorChannel' are mutually exclusive.");
|
||||
this.historyWritingPostProcessor.setTrackableComponent(this);
|
||||
this.historyWritingPostProcessor.setMessageBuilderFactory(this.getMessageBuilderFactory());
|
||||
if (this.getBeanFactory() != null) {
|
||||
@@ -191,17 +232,79 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
}
|
||||
}
|
||||
|
||||
private MessageChannel getRequestChannel() {
|
||||
if (this.requestChannelName != null) {
|
||||
synchronized (this) {
|
||||
if (this.requestChannelName != null) {
|
||||
try {
|
||||
Assert.state(getBeanFactory() != null,
|
||||
"A bean factory is required to resolve the requestChannel at runtime.");
|
||||
this.requestChannel = getBeanFactory().getBean(this.requestChannelName, MessageChannel.class);
|
||||
this.requestChannelName = null;
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.requestChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.requestChannel;
|
||||
}
|
||||
|
||||
private MessageChannel getReplyChannel() {
|
||||
if (this.replyChannelName != null) {
|
||||
synchronized (this) {
|
||||
if (this.replyChannelName != null) {
|
||||
try {
|
||||
Assert.state(getBeanFactory() != null,
|
||||
"A bean factory is required to resolve the replyChannel at runtime.");
|
||||
this.replyChannel = getBeanFactory().getBean(this.replyChannelName, MessageChannel.class);
|
||||
this.replyChannelName = null;
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.replyChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.replyChannel;
|
||||
}
|
||||
|
||||
private MessageChannel getErrorChannel() {
|
||||
if (this.errorChannelName != null) {
|
||||
synchronized (this) {
|
||||
if (this.errorChannelName != null) {
|
||||
try {
|
||||
Assert.state(getBeanFactory() != null,
|
||||
"A bean factory is required to resolve the errorChannel at runtime.");
|
||||
this.errorChannel = getBeanFactory().getBean(this.errorChannelName, MessageChannel.class);
|
||||
this.errorChannelName = null;
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.errorChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.errorChannel;
|
||||
}
|
||||
|
||||
protected void send(Object object) {
|
||||
this.initializeIfNecessary();
|
||||
Assert.notNull(object, "request must not be null");
|
||||
Assert.state(this.requestChannel != null,
|
||||
MessageChannel requestChannel = getRequestChannel();
|
||||
Assert.state(requestChannel != null,
|
||||
"send is not supported, because no request channel has been configured");
|
||||
try {
|
||||
this.messagingTemplate.convertAndSend(this.requestChannel, object, this.historyWritingPostProcessor);
|
||||
this.messagingTemplate.convertAndSend(requestChannel, object, this.historyWritingPostProcessor);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (this.errorChannel != null) {
|
||||
this.messagingTemplate.send(this.errorChannel, new ErrorMessage(e));
|
||||
MessageChannel errorChannel = getErrorChannel();
|
||||
if (errorChannel != null) {
|
||||
this.messagingTemplate.send(errorChannel, new ErrorMessage(e));
|
||||
}
|
||||
else {
|
||||
this.rethrow(e, "failed to send message");
|
||||
@@ -211,9 +314,10 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
|
||||
protected Object receive() {
|
||||
this.initializeIfNecessary();
|
||||
Assert.state(this.replyChannel != null && (this.replyChannel instanceof PollableChannel),
|
||||
MessageChannel replyChannel = getReplyChannel();
|
||||
Assert.state(replyChannel != null && (replyChannel instanceof PollableChannel),
|
||||
"receive is not supported, because no pollable reply channel has been configured");
|
||||
return this.messagingTemplate.receiveAndConvert((PollableChannel) this.replyChannel, null);
|
||||
return this.messagingTemplate.receiveAndConvert(replyChannel, null);
|
||||
}
|
||||
|
||||
protected Object sendAndReceive(Object object) {
|
||||
@@ -228,17 +332,20 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
private Object doSendAndReceive(Object object, boolean shouldConvert) {
|
||||
this.initializeIfNecessary();
|
||||
Assert.notNull(object, "request must not be null");
|
||||
if (this.requestChannel == null) {
|
||||
MessageChannel requestChannel = getRequestChannel();
|
||||
if (requestChannel == null) {
|
||||
throw new MessagingException("No request channel available. Cannot send request message.");
|
||||
}
|
||||
if (this.replyChannel != null && this.replyMessageCorrelator == null) {
|
||||
MessageChannel replyChannel = getReplyChannel();
|
||||
if (replyChannel != null && this.replyMessageCorrelator == null) {
|
||||
this.registerReplyMessageCorrelator();
|
||||
}
|
||||
Object reply = null;
|
||||
Throwable error = null;
|
||||
try {
|
||||
if (shouldConvert) {
|
||||
reply = this.messagingTemplate.convertSendAndReceive(this.requestChannel, object, null, this.historyWritingPostProcessor);
|
||||
reply = this.messagingTemplate.convertSendAndReceive(requestChannel, object, null,
|
||||
this.historyWritingPostProcessor);
|
||||
if (reply instanceof Throwable) {
|
||||
error = (Throwable) reply;
|
||||
}
|
||||
@@ -247,7 +354,7 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
Message<?> requestMessage = (object instanceof Message<?>)
|
||||
? (Message<?>) object : this.requestMapper.toMessage(object);
|
||||
requestMessage = this.historyWritingPostProcessor.postProcessMessage(requestMessage);
|
||||
reply = this.messagingTemplate.sendAndReceive(this.requestChannel, requestMessage);
|
||||
reply = this.messagingTemplate.sendAndReceive(requestChannel, requestMessage);
|
||||
if (reply instanceof ErrorMessage) {
|
||||
error = ((ErrorMessage) reply).getPayload();
|
||||
}
|
||||
@@ -261,14 +368,16 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
}
|
||||
|
||||
if (error != null) {
|
||||
if (this.errorChannel != null) {
|
||||
MessageChannel errorChannel = getErrorChannel();
|
||||
if (errorChannel != null) {
|
||||
Message<?> errorMessage = new ErrorMessage(error);
|
||||
Message<?> errorFlowReply = null;
|
||||
try {
|
||||
errorFlowReply = this.messagingTemplate.sendAndReceive(this.errorChannel, errorMessage);
|
||||
errorFlowReply = this.messagingTemplate.sendAndReceive(errorChannel, errorMessage);
|
||||
}
|
||||
catch (Exception errorFlowFailure) {
|
||||
throw new MessagingException(errorMessage, "failure occurred in error-handling flow", errorFlowFailure);
|
||||
throw new MessagingException(errorMessage, "failure occurred in error-handling flow",
|
||||
errorFlowFailure);
|
||||
}
|
||||
if (shouldConvert) {
|
||||
Object result = (errorFlowReply != null) ? errorFlowReply.getPayload() : null;
|
||||
@@ -307,18 +416,21 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
handler.setBeanFactory(this.getBeanFactory());
|
||||
}
|
||||
handler.afterPropertiesSet();
|
||||
if (this.replyChannel instanceof SubscribableChannel) {
|
||||
correlator = new EventDrivenConsumer(
|
||||
(SubscribableChannel) this.replyChannel, handler);
|
||||
MessageChannel replyChannel = getReplyChannel();
|
||||
if (replyChannel instanceof SubscribableChannel) {
|
||||
correlator = new EventDrivenConsumer((SubscribableChannel) replyChannel, handler);
|
||||
}
|
||||
else if (this.replyChannel instanceof PollableChannel) {
|
||||
PollingConsumer endpoint = new PollingConsumer(
|
||||
(PollableChannel) this.replyChannel, handler);
|
||||
else if (replyChannel instanceof PollableChannel) {
|
||||
PollingConsumer endpoint = new PollingConsumer((PollableChannel) replyChannel, handler);
|
||||
endpoint.setBeanFactory(this.getBeanFactory());
|
||||
endpoint.setReceiveTimeout(this.replyTimeout);
|
||||
endpoint.afterPropertiesSet();
|
||||
correlator = endpoint;
|
||||
}
|
||||
else {
|
||||
throw new MessagingException("Unsupported 'replyChannel' type [" + replyChannel.getClass() + "]."
|
||||
+ "SubscribableChannel or PollableChannel type are supported.");
|
||||
}
|
||||
if (this.isRunning()) {
|
||||
correlator.start();
|
||||
}
|
||||
@@ -356,6 +468,7 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
|
||||
}
|
||||
return (object != null) ? this.messageBuilderFactory.withPayload(object).build() : null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Content Enricher is a Message Transformer that can augment a message's payload with
|
||||
@@ -55,6 +54,8 @@ import org.springframework.util.StringUtils;
|
||||
public class ContentEnricher extends AbstractReplyProducingMessageHandler
|
||||
implements Lifecycle, IntegrationEvaluationContextAware {
|
||||
|
||||
private final SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
|
||||
private volatile Map<Expression, Expression> nullResultPropertyExpressions = new HashMap<Expression, Expression>();
|
||||
|
||||
private volatile Map<String, HeaderValueMessageProcessor<?>> nullResultHeaderExpressions =
|
||||
@@ -65,8 +66,6 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler
|
||||
private volatile Map<String, HeaderValueMessageProcessor<?>> headerExpressions =
|
||||
new HashMap<String, HeaderValueMessageProcessor<?>>();
|
||||
|
||||
private final SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
|
||||
private EvaluationContext sourceEvaluationContext;
|
||||
|
||||
private EvaluationContext targetEvaluationContext;
|
||||
@@ -149,6 +148,7 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler
|
||||
}
|
||||
|
||||
public void setRequestChannelName(String requestChannelName) {
|
||||
Assert.hasText(requestChannelName, "'requestChannelName' must not be empty");
|
||||
this.requestChannelName = requestChannelName;
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler
|
||||
}
|
||||
|
||||
public void setReplyChannelName(String replyChannelName) {
|
||||
Assert.hasText(replyChannelName, "'replyChannelName' must not be empty");
|
||||
this.replyChannelName = replyChannelName;
|
||||
}
|
||||
|
||||
@@ -239,33 +240,33 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler
|
||||
*/
|
||||
@Override
|
||||
protected void doInit() {
|
||||
if (StringUtils.hasText(this.requestChannelName)) {
|
||||
Assert.isNull(this.requestChannel, "'requestChannelName' and 'requestChannel' are mutually exclusive.");
|
||||
this.requestChannel = this.getBeanFactory().getBean(this.requestChannelName, MessageChannel.class);
|
||||
}
|
||||
Assert.state(!(this.requestChannelName != null && this.requestChannel != null),
|
||||
"'requestChannelName' and 'requestChannel' are mutually exclusive.");
|
||||
|
||||
if (StringUtils.hasText(this.replyChannelName)) {
|
||||
Assert.isNull(this.replyChannel, "'replyChannelName' and 'replyChannel' are mutually exclusive.");
|
||||
this.replyChannel = this.getBeanFactory().getBean(this.replyChannelName, MessageChannel.class);
|
||||
}
|
||||
Assert.state(!(this.replyChannelName != null && this.replyChannel != null),
|
||||
"'replyChannelName' and 'replyChannel' are mutually exclusive.");
|
||||
|
||||
if (this.replyChannel != null) {
|
||||
Assert.notNull(this.requestChannel, "If the replyChannel is set, then the requestChannel must not be null");
|
||||
if (this.replyChannel != null || this.replyChannelName != null) {
|
||||
Assert.state(this.requestChannel != null || this.requestChannelName != null,
|
||||
"If the replyChannel is set, then the requestChannel must not be null");
|
||||
}
|
||||
if (this.requestChannel != null) {
|
||||
if (this.requestChannel != null || this.requestChannelName != null) {
|
||||
this.gateway = new Gateway();
|
||||
this.gateway.setRequestChannel(requestChannel);
|
||||
this.gateway.setRequestChannel(this.requestChannel);
|
||||
if (this.requestChannelName != null) {
|
||||
this.gateway.setRequestChannelName(this.requestChannelName);
|
||||
}
|
||||
|
||||
if (this.requestTimeout != null) {
|
||||
this.gateway.setRequestTimeout(this.requestTimeout);
|
||||
}
|
||||
|
||||
if (this.replyTimeout != null) {
|
||||
this.gateway.setReplyTimeout(this.replyTimeout);
|
||||
}
|
||||
|
||||
if (replyChannel != null) {
|
||||
this.gateway.setReplyChannel(replyChannel);
|
||||
this.gateway.setReplyChannel(replyChannel);
|
||||
if (this.replyChannelName != null) {
|
||||
this.gateway.setReplyChannelName(this.replyChannelName);
|
||||
}
|
||||
|
||||
if (this.getBeanFactory() != null) {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
</enricher>
|
||||
|
||||
<enricher input-channel="input2" output-channel="output">
|
||||
<header name="foo" expression="new java.util.Date()" type="int"/>
|
||||
<header name="foo" expression="new java.util.Date()"/>
|
||||
</enricher>
|
||||
|
||||
<util:constant id="testBean" static-field="org.springframework.integration.config.xml.EnricherParserTests$Gender.MALE"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -34,6 +34,7 @@ import org.springframework.beans.TypeMismatchException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
|
||||
@@ -44,7 +45,6 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandlingException;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -82,7 +82,8 @@ public class EnricherParserTests {
|
||||
assertNull(accessor.getPropertyValue("requestPayloadExpression"));
|
||||
assertNotNull(TestUtils.getPropertyValue(enricher, "gateway.beanFactory"));
|
||||
|
||||
Map<Expression, Expression> propertyExpressions = (Map<Expression, Expression>) accessor.getPropertyValue("propertyExpressions");
|
||||
Map<Expression, Expression> propertyExpressions =
|
||||
(Map<Expression, Expression>) accessor.getPropertyValue("propertyExpressions");
|
||||
for (Map.Entry<Expression, Expression> e : propertyExpressions.entrySet()) {
|
||||
if ("name".equals(e.getKey().getExpressionString())) {
|
||||
assertEquals("payload.sourceName", e.getValue().getExpressionString());
|
||||
@@ -110,7 +111,7 @@ public class EnricherParserTests {
|
||||
Object endpoint = context.getBean("enricher");
|
||||
|
||||
Long requestTimeout = TestUtils.getPropertyValue(endpoint, "handler.requestTimeout", Long.class);
|
||||
Long replyTimeout = TestUtils.getPropertyValue(endpoint, "handler.replyTimeout", Long.class);
|
||||
Long replyTimeout = TestUtils.getPropertyValue(endpoint, "handler.replyTimeout", Long.class);
|
||||
|
||||
assertEquals(Long.valueOf(1234L), requestTimeout);
|
||||
assertEquals(Long.valueOf(9876L), replyTimeout);
|
||||
@@ -130,6 +131,9 @@ public class EnricherParserTests {
|
||||
|
||||
@Test
|
||||
public void integrationTest() {
|
||||
QueueChannel output = context.getBean("output", QueueChannel.class);
|
||||
output.purge(null);
|
||||
|
||||
SubscribableChannel requests = context.getBean("requests", SubscribableChannel.class);
|
||||
|
||||
class Foo extends AbstractReplyProducingMessageHandler {
|
||||
@@ -149,7 +153,8 @@ public class EnricherParserTests {
|
||||
.setHeader("notOverwrite", "test")
|
||||
.build();
|
||||
context.getBean("input", MessageChannel.class).send(request);
|
||||
Message<?> reply = context.getBean("output", PollableChannel.class).receive(0);
|
||||
|
||||
Message<?> reply = output.receive(0);
|
||||
Target enriched = (Target) reply.getPayload();
|
||||
assertEquals("foo", enriched.getName());
|
||||
assertEquals(42, enriched.getAge());
|
||||
@@ -193,6 +198,7 @@ public class EnricherParserTests {
|
||||
public String getSourceName() {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Target implements Cloneable {
|
||||
@@ -246,10 +252,12 @@ public class EnricherParserTests {
|
||||
copy.setMarried(this.married);
|
||||
return copy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static enum Gender {
|
||||
MALE, FEMALE
|
||||
|
||||
}
|
||||
|
||||
public static class FooAdvice extends AbstractRequestHandlerAdvice {
|
||||
@@ -261,4 +269,5 @@ public class EnricherParserTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -118,7 +118,8 @@ public class ContentEnricherTests {
|
||||
protected Object handleRequestMessage(Message<?> requestMessage) {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
return new Target("child");
|
||||
@@ -144,7 +145,8 @@ public class ContentEnricherTests {
|
||||
|
||||
try {
|
||||
enricher.handleMessage(requestMessage);
|
||||
} catch (ReplyRequiredException e) {
|
||||
}
|
||||
catch (ReplyRequiredException e) {
|
||||
assertEquals("No reply produced by handler 'Enricher', and its 'requiresReply' property is set to true.", e.getMessage());
|
||||
return;
|
||||
}
|
||||
@@ -173,8 +175,9 @@ public class ContentEnricherTests {
|
||||
Message<?> requestMessage = MessageBuilder.withPayload(target).setReplyChannel(replyChannel).build();
|
||||
|
||||
try {
|
||||
enricher.handleMessage(requestMessage);
|
||||
} catch (MessageDeliveryException e) {
|
||||
enricher.handleMessage(requestMessage);
|
||||
}
|
||||
catch (MessageDeliveryException e) {
|
||||
assertEquals("failed to send message to channel '" + requestChannelName
|
||||
+ "' within timeout: " + requestTimeout, e.getMessage());
|
||||
return;
|
||||
@@ -220,8 +223,9 @@ public class ContentEnricherTests {
|
||||
enricher.setBeanFactory(mock(BeanFactory.class));
|
||||
|
||||
try {
|
||||
enricher.afterPropertiesSet();
|
||||
} catch (IllegalArgumentException e) {
|
||||
enricher.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
assertEquals("If the replyChannel is set, then the requestChannel must not be null", e.getMessage());
|
||||
return;
|
||||
}
|
||||
@@ -236,8 +240,9 @@ public class ContentEnricherTests {
|
||||
enricher.setBeanFactory(mock(BeanFactory.class));
|
||||
|
||||
try {
|
||||
enricher.setReplyTimeout(null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
enricher.setReplyTimeout(null);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertEquals("replyTimeout must not be null", e.getMessage());
|
||||
return;
|
||||
}
|
||||
@@ -252,8 +257,9 @@ public class ContentEnricherTests {
|
||||
enricher.setBeanFactory(mock(BeanFactory.class));
|
||||
|
||||
try {
|
||||
enricher.setRequestTimeout(null);
|
||||
} catch (IllegalArgumentException e) {
|
||||
enricher.setRequestTimeout(null);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertEquals("requestTimeout must not be null", e.getMessage());
|
||||
return;
|
||||
}
|
||||
@@ -286,10 +292,11 @@ public class ContentEnricherTests {
|
||||
enricher.setBeanFactory(mock(BeanFactory.class));
|
||||
|
||||
try {
|
||||
enricher.afterPropertiesSet();
|
||||
} catch (IllegalArgumentException e) {
|
||||
assertEquals("If the replyChannel is set, then the requestChannel must not be null", e.getMessage());
|
||||
return;
|
||||
enricher.afterPropertiesSet();
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
assertEquals("If the replyChannel is set, then the requestChannel must not be null", e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Expected an IllegalArgumentException to be thrown.");
|
||||
@@ -414,10 +421,11 @@ public class ContentEnricherTests {
|
||||
Message<?> requestMessage = MessageBuilder.withPayload(target).setReplyChannel(replyChannel).build();
|
||||
|
||||
try {
|
||||
enricher.handleMessage(requestMessage);
|
||||
} catch (MessageHandlingException e) {
|
||||
enricher.handleMessage(requestMessage);
|
||||
}
|
||||
catch (MessageHandlingException e) {
|
||||
assertThat(e.getMessage(), containsString("Failed to clone payload object"));
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Expected a MessageHandlingException to be thrown.");
|
||||
@@ -478,6 +486,7 @@ public class ContentEnricherTests {
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -517,6 +526,7 @@ public class ContentEnricherTests {
|
||||
clone.setChild(this.child);
|
||||
return clone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class TargetUser {
|
||||
@@ -557,6 +567,7 @@ public class ContentEnricherTests {
|
||||
public Object clone() {
|
||||
throw new IllegalStateException("Cloning not possible");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user