INT-3402: Late Resolution for Channel Names
JIRA: https://jira.spring.io/browse/INT-3402 * Move `channel name to channel` resolution logic to the action, e.g. `sendReplyMessage` * Remove resolution logic from `MessagingAnnotation` Processors * Fix `AggregatorAnnotationPostProcessor` to invoke `handler.afterPropertiesSet()` one more time, because of `AbstractMethodAnnotationPostProcessor` `this.beanFactory.initializeBean(handler, handlerBeanName)` * `Filter` annotation: allow `property-placeholder` for the `discardWithinAdvice` * Fix `EnricherParserTests4-context.xml` duration: use just `0` for the `reply-timeout` INT-3402: Add `synchronized double check` INT-3402: Polishing according PR comments INT-3402: Optimization for `AbstractCorrelatingMH`
This commit is contained in:
committed by
Gary Russell
parent
403c91801d
commit
1458f56102
@@ -57,7 +57,6 @@ import org.springframework.messaging.core.DestinationResolutionException;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Abstract Message handler that holds a buffer of correlated messages in a
|
||||
@@ -187,6 +186,7 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
}
|
||||
|
||||
public void setOutputChannelName(String outputChannelName) {
|
||||
Assert.hasText(outputChannelName, "'outputChannelName' must not be empty");
|
||||
this.outputChannelName = outputChannelName;
|
||||
}
|
||||
|
||||
@@ -215,27 +215,11 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
BeanFactory beanFactory = this.getBeanFactory();
|
||||
if (beanFactory != null) {
|
||||
this.messagingTemplate.setBeanFactory(beanFactory);
|
||||
if (StringUtils.hasText(this.discardChannelName)) {
|
||||
Assert.isNull(this.discardChannel, "'outputChannelName' and 'discardChannel' are mutually exclusive.");
|
||||
try {
|
||||
this.discardChannel = beanFactory.getBean(this.discardChannelName, MessageChannel.class);
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.discardChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
Assert.state(!(this.discardChannelName != null && this.discardChannel != null),
|
||||
"'discardChannelName' and 'discardChannel' are mutually exclusive.");
|
||||
|
||||
if (StringUtils.hasText(this.outputChannelName)) {
|
||||
Assert.isNull(this.outputChannel, "'outputChannelName' and 'outputChannel' are mutually exclusive.");
|
||||
try {
|
||||
this.outputChannel = this.getBeanFactory().getBean(this.outputChannelName, MessageChannel.class);
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.outputChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
Assert.state(!(this.outputChannelName != null && this.outputChannel != null),
|
||||
"'outputChannelName' and 'outputChannel' are mutually exclusive.");
|
||||
|
||||
if (this.outputProcessor instanceof BeanFactoryAware) {
|
||||
((BeanFactoryAware) this.outputProcessor).setBeanFactory(beanFactory);
|
||||
@@ -272,6 +256,7 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
}
|
||||
|
||||
public void setDiscardChannelName(String discardChannelName) {
|
||||
Assert.hasText(discardChannelName, "'discardChannelName' must not be empty");
|
||||
this.discardChannelName = discardChannelName;
|
||||
}
|
||||
|
||||
@@ -291,7 +276,6 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
* schedule than expiring partial groups, set this property. Empty groups will
|
||||
* then not be removed from the MessageStore until they have not been modified
|
||||
* for at least this number of milliseconds.
|
||||
*
|
||||
* @param minimumTimeoutForEmptyGroups The minimum timeout.
|
||||
*/
|
||||
public void setMinimumTimeoutForEmptyGroups(long minimumTimeoutForEmptyGroups) {
|
||||
@@ -461,7 +445,7 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
}
|
||||
}
|
||||
else {
|
||||
discardChannel.send(message);
|
||||
discardMessage(message);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -469,6 +453,24 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
}
|
||||
}
|
||||
|
||||
private void discardMessage(Message<?> message) {
|
||||
if (this.discardChannelName != null) {
|
||||
synchronized (this) {
|
||||
if (this.discardChannelName != null) {
|
||||
try {
|
||||
this.discardChannel = getBeanFactory().getBean(this.discardChannelName, MessageChannel.class);
|
||||
this.discardChannelName = null;
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.discardChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.discardChannel.send(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to provide additional logic that needs to be performed after the MessageGroup was released.
|
||||
* @param group The group.
|
||||
@@ -591,17 +593,19 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
if (sendPartialResultOnExpiry) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Prematurely releasing partially complete group with key ["
|
||||
+ correlationKey + "] to: " + outputChannel);
|
||||
+ correlationKey + "] to: "
|
||||
+ (this.outputChannelName != null ? this.outputChannelName : this.outputChannel));
|
||||
}
|
||||
completeGroup(correlationKey, group);
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Discarding messages of partially complete group with key ["
|
||||
+ correlationKey + "] to: " + discardChannel);
|
||||
+ correlationKey + "] to: "
|
||||
+ (this.discardChannelName != null ? this.discardChannelName : this.discardChannel));
|
||||
}
|
||||
for (Message<?> message : group.getMessages()) {
|
||||
discardChannel.send(message);
|
||||
discardMessage(message);
|
||||
}
|
||||
}
|
||||
if (this.applicationEventPublisher != null) {
|
||||
@@ -645,6 +649,22 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
if (message != null) {
|
||||
replyChannelHeader = message.getHeaders().getReplyChannel();
|
||||
}
|
||||
|
||||
if (this.outputChannelName != null) {
|
||||
synchronized (this) {
|
||||
if (this.outputChannelName != null) {
|
||||
try {
|
||||
this.outputChannel = getBeanFactory().getBean(this.outputChannelName, MessageChannel.class);
|
||||
this.outputChannelName = null;
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.outputChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object replyChannel = this.outputChannel;
|
||||
if (this.outputChannel == null) {
|
||||
replyChannel = replyChannelHeader;
|
||||
@@ -718,12 +738,8 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
Integer messageSequenceNumber = messageHeaderAccessor.getSequenceNumber();
|
||||
if (messageSequenceNumber != null && messageSequenceNumber > 0) {
|
||||
Integer messageSequenceSize = messageHeaderAccessor.getSequenceSize();
|
||||
if (!messageSequenceSize.equals(this.getSequenceSize())) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return !this.containsSequenceNumber(this.getMessages(), messageSequenceNumber);
|
||||
}
|
||||
return messageSequenceSize.equals(this.getSequenceSize())
|
||||
&& !this.containsSequenceNumber(this.getMessages(), messageSequenceNumber);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -738,4 +754,5 @@ public abstract class AbstractCorrelatingMessageHandler extends AbstractMessageH
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public @interface Filter {
|
||||
|
||||
String[] adviceChain() default {};
|
||||
|
||||
boolean discardWithinAdvice() default true;
|
||||
String discardWithinAdvice() default "true";
|
||||
|
||||
/*
|
||||
{@code SmartLifecycle} options.
|
||||
|
||||
@@ -70,6 +70,7 @@ public class PublisherAnnotationBeanPostProcessor extends ProxyConfig
|
||||
/**
|
||||
* Set the default channel where Messages should be sent if the annotation
|
||||
* itself does not provide a channel.
|
||||
* @param defaultChannelName the publisher interceptor defaultChannel
|
||||
* @since 4.0.3
|
||||
*/
|
||||
public void setDefaultChannelName(String defaultChannelName) {
|
||||
|
||||
@@ -319,7 +319,7 @@ public abstract class AbstractMethodAnnotationPostProcessor<T extends Annotation
|
||||
protected void setOutputChannelIfPresent(List<Annotation> annotations, AbstractReplyProducingMessageHandler handler) {
|
||||
String outputChannelName = MessagingAnnotationUtils.resolveAttribute(annotations, "outputChannel", String.class);
|
||||
if (StringUtils.hasText(outputChannelName)) {
|
||||
handler.setOutputChannel(this.channelResolver.resolveDestination(outputChannelName));
|
||||
handler.setOutputChannelName(outputChannelName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,9 +30,7 @@ import org.springframework.integration.annotation.Aggregator;
|
||||
import org.springframework.integration.annotation.CorrelationStrategy;
|
||||
import org.springframework.integration.annotation.ReleaseStrategy;
|
||||
import org.springframework.integration.store.SimpleMessageStore;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -72,13 +70,11 @@ public class AggregatorAnnotationPostProcessor extends AbstractMethodAnnotationP
|
||||
|
||||
String discardChannelName = MessagingAnnotationUtils.resolveAttribute(annotations, "discardChannel", String.class);
|
||||
if (StringUtils.hasText(discardChannelName)) {
|
||||
MessageChannel discardChannel = this.channelResolver.resolveDestination(discardChannelName);
|
||||
Assert.notNull(discardChannel, "failed to resolve discardChannel '" + discardChannelName + "'");
|
||||
handler.setDiscardChannel(discardChannel);
|
||||
handler.setDiscardChannelName(discardChannelName);
|
||||
}
|
||||
String outputChannelName = MessagingAnnotationUtils.resolveAttribute(annotations, "outputChannel", String.class);
|
||||
if (StringUtils.hasText(outputChannelName)) {
|
||||
handler.setOutputChannel(this.channelResolver.resolveDestination(outputChannelName));
|
||||
handler.setOutputChannelName(outputChannelName);
|
||||
}
|
||||
Long sendTimeout = MessagingAnnotationUtils.resolveAttribute(annotations, "sendTimeout", Long.class);
|
||||
if (sendTimeout != null) {
|
||||
@@ -90,7 +86,6 @@ public class AggregatorAnnotationPostProcessor extends AbstractMethodAnnotationP
|
||||
handler.setSendPartialResultOnExpiry(sendPartialResultsOnExpiry);
|
||||
}
|
||||
handler.setBeanFactory(this.beanFactory);
|
||||
handler.afterPropertiesSet();
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.integration.handler.BridgeHandler;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Post-processor for the {@link BridgeTo @BridgeTo} annotation.
|
||||
@@ -64,7 +65,9 @@ public class BridgeToAnnotationPostProcessor extends AbstractMethodAnnotationPos
|
||||
protected MessageHandler createHandler(Object bean, Method method, List<Annotation> annotations) {
|
||||
BridgeHandler handler = new BridgeHandler();
|
||||
String outputChannelName = MessagingAnnotationUtils.resolveAttribute(annotations, "value", String.class);
|
||||
handler.setOutputChannelName(outputChannelName);
|
||||
if (StringUtils.hasText(outputChannelName)) {
|
||||
handler.setOutputChannelName(outputChannelName);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,28 +70,29 @@ public class FilterAnnotationPostProcessor extends AbstractMethodAnnotationPostP
|
||||
|
||||
MessageFilter filter = new MessageFilter(selector);
|
||||
|
||||
/* TODO will be revised in the future
|
||||
String discardWithinAdvice = MessagingAnnotationUtils.resolveAttribute(annotations, "discardWithinAdvice",
|
||||
String.class);
|
||||
if (StringUtils.hasText(discardWithinAdvice)) {
|
||||
String discardWithinAdviceValue = this.environment.resolvePlaceholders(discardWithinAdvice);
|
||||
if (StringUtils.hasText(discardWithinAdviceValue)) {
|
||||
filter.setDiscardWithinAdvice(Boolean.parseBoolean(discardWithinAdviceValue));
|
||||
discardWithinAdvice = this.environment.resolvePlaceholders(discardWithinAdvice);
|
||||
if (StringUtils.hasText(discardWithinAdvice)) {
|
||||
filter.setDiscardWithinAdvice(Boolean.parseBoolean(discardWithinAdvice));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
filter.setDiscardWithinAdvice(MessagingAnnotationUtils.resolveAttribute(annotations, "discardWithinAdvice",
|
||||
Boolean.class));
|
||||
|
||||
String throwExceptionOnRejection = MessagingAnnotationUtils.resolveAttribute(annotations,
|
||||
"throwExceptionOnRejection", String.class);
|
||||
if (StringUtils.hasText(throwExceptionOnRejection)) {
|
||||
String throwExceptionOnRejectionValue = this.environment.resolvePlaceholders(throwExceptionOnRejection);
|
||||
filter.setThrowExceptionOnRejection(Boolean.parseBoolean(throwExceptionOnRejectionValue));
|
||||
if (StringUtils.hasText(throwExceptionOnRejectionValue)) {
|
||||
filter.setThrowExceptionOnRejection(Boolean.parseBoolean(throwExceptionOnRejectionValue));
|
||||
}
|
||||
}
|
||||
|
||||
String discardChannelName = MessagingAnnotationUtils.resolveAttribute(annotations, "discardChannel", String.class);
|
||||
filter.setDiscardChannelName(discardChannelName);
|
||||
if (StringUtils.hasText(discardChannelName)) {
|
||||
filter.setDiscardChannelName(discardChannelName);
|
||||
}
|
||||
|
||||
this.setOutputChannelIfPresent(annotations, filter);
|
||||
return filter;
|
||||
|
||||
@@ -75,7 +75,9 @@ public class RouterAnnotationPostProcessor extends AbstractMethodAnnotationPostP
|
||||
}
|
||||
String defaultOutputChannelName = MessagingAnnotationUtils.resolveAttribute(annotations,
|
||||
"defaultOutputChannel", String.class);
|
||||
router.setDefaultOutputChannelName(defaultOutputChannelName);
|
||||
if (StringUtils.hasText(defaultOutputChannelName)) {
|
||||
router.setDefaultOutputChannelName(defaultOutputChannelName);
|
||||
}
|
||||
|
||||
String applySequence = MessagingAnnotationUtils.resolveAttribute(annotations, "applySequence", String.class);
|
||||
if (StringUtils.hasText(applySequence)) {
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.core.DestinationResolutionException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Message Handler that delegates to a {@link MessageSelector}. If and only if
|
||||
@@ -52,9 +51,7 @@ public class MessageFilter extends AbstractReplyProducingPostProcessingMessageHa
|
||||
private volatile String discardChannelName;
|
||||
|
||||
/**
|
||||
* Create a MessageFilter that will delegate to the given
|
||||
* {@link MessageSelector}.
|
||||
*
|
||||
* Create a MessageFilter that will delegate to the given {@link MessageSelector}.
|
||||
* @param selector The message selector.
|
||||
*/
|
||||
public MessageFilter(MessageSelector selector) {
|
||||
@@ -72,9 +69,8 @@ public class MessageFilter extends AbstractReplyProducingPostProcessingMessageHa
|
||||
* a discard channel is provided, but if so, it will still apply
|
||||
* (in such a case, the Message will be sent to the discard channel,
|
||||
* and <em>then</em> the exception will be thrown).
|
||||
* @see #setDiscardChannel(MessageChannel)
|
||||
*
|
||||
* @param throwExceptionOnRejection true if an exception should be thrown.
|
||||
* @see #setDiscardChannel(MessageChannel)
|
||||
*/
|
||||
public void setThrowExceptionOnRejection(boolean throwExceptionOnRejection) {
|
||||
this.throwExceptionOnRejection = throwExceptionOnRejection;
|
||||
@@ -86,9 +82,7 @@ public class MessageFilter extends AbstractReplyProducingPostProcessingMessageHa
|
||||
* the 'throwExceptionOnRejection' flag determines whether rejected Messages
|
||||
* trigger an exception. That value is evaluated regardless of the presence
|
||||
* of a discard channel.
|
||||
*
|
||||
* @param discardChannel The discard channel.
|
||||
*
|
||||
* @see #setThrowExceptionOnRejection(boolean)
|
||||
*/
|
||||
public void setDiscardChannel(MessageChannel discardChannel) {
|
||||
@@ -96,6 +90,7 @@ public class MessageFilter extends AbstractReplyProducingPostProcessingMessageHa
|
||||
}
|
||||
|
||||
public void setDiscardChannelName(String discardChannelName) {
|
||||
Assert.hasText(discardChannelName, "'discardChannelName' must not be empty");
|
||||
this.discardChannelName = discardChannelName;
|
||||
}
|
||||
|
||||
@@ -103,7 +98,6 @@ public class MessageFilter extends AbstractReplyProducingPostProcessingMessageHa
|
||||
* Set to 'true' if you wish the discard processing to occur within any
|
||||
* request handler advice applied to this filter. Also applies to
|
||||
* throwing an exception on rejection. Default: true.
|
||||
*
|
||||
* @param discardWithinAdvice true to discard within the advice.
|
||||
*/
|
||||
public void setDiscardWithinAdvice(boolean discardWithinAdvice) {
|
||||
@@ -117,16 +111,8 @@ public class MessageFilter extends AbstractReplyProducingPostProcessingMessageHa
|
||||
|
||||
@Override
|
||||
protected void doInit() {
|
||||
if (StringUtils.hasText(this.discardChannelName)) {
|
||||
Assert.isNull(this.discardChannel, "'outputChannelName' and 'discardChannel' are mutually exclusive.");
|
||||
try {
|
||||
this.discardChannel = this.getBeanFactory().getBean(this.discardChannelName, MessageChannel.class);
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.discardChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
Assert.state(!(this.discardChannelName != null && this.discardChannel != null),
|
||||
"'discardChannelName' and 'discardChannel' are mutually exclusive.");
|
||||
if (this.selector instanceof AbstractMessageProcessingSelector) {
|
||||
((AbstractMessageProcessingSelector) this.selector).setConversionService(this.getConversionService());
|
||||
}
|
||||
@@ -148,11 +134,27 @@ public class MessageFilter extends AbstractReplyProducingPostProcessingMessageHa
|
||||
@Override
|
||||
public Object postProcess(Message<?> message, Object result) {
|
||||
if (result == null) {
|
||||
if (this.discardChannelName != null) {
|
||||
synchronized (this) {
|
||||
if (this.discardChannelName != null) {
|
||||
try {
|
||||
this.discardChannel = this.getBeanFactory()
|
||||
.getBean(this.discardChannelName, MessageChannel.class);
|
||||
this.discardChannelName = null;
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.discardChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.discardChannel != null) {
|
||||
this.getMessagingTemplate().send(this.discardChannel, message);
|
||||
}
|
||||
if (this.throwExceptionOnRejection) {
|
||||
throw new MessageRejectedException(message, "MessageFilter '" + this.getComponentName() + "' rejected Message");
|
||||
throw new MessageRejectedException(message, "MessageFilter '" + this.getComponentName()
|
||||
+ "' rejected Message");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -35,7 +35,6 @@ import org.springframework.messaging.core.DestinationResolver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for MessageHandlers that are capable of producing replies.
|
||||
@@ -44,6 +43,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Iwein Fuld
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public abstract class AbstractReplyProducingMessageHandler extends AbstractMessageHandler
|
||||
implements MessageProducer, BeanClassLoaderAware {
|
||||
@@ -75,12 +75,12 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
}
|
||||
|
||||
public void setOutputChannelName(String outputChannelName) {
|
||||
Assert.hasText(outputChannelName, "'outputChannelName' must not be empty");
|
||||
this.outputChannelName = outputChannelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timeout for sending reply Messages.
|
||||
*
|
||||
* @param sendTimeout The send timeout.
|
||||
*/
|
||||
public void setSendTimeout(long sendTimeout) {
|
||||
@@ -89,7 +89,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
|
||||
/**
|
||||
* Set the DestinationResolver<MessageChannel> to be used when there is no default output channel.
|
||||
*
|
||||
* @param channelResolver The channel resolver.
|
||||
*/
|
||||
public void setChannelResolver(DestinationResolver<MessageChannel> channelResolver) {
|
||||
@@ -100,7 +99,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
/**
|
||||
* Flag whether a reply is required. If true an incoming message MUST result in a reply message being sent.
|
||||
* If false an incoming message MAY result in a reply message being sent. Default is false.
|
||||
*
|
||||
* @param requiresReply true if a reply is required.
|
||||
*/
|
||||
public void setRequiresReply(boolean requiresReply) {
|
||||
@@ -109,7 +107,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
|
||||
/**
|
||||
* Provides access to the {@link MessagingTemplate} for subclasses.
|
||||
*
|
||||
* @return The messaging template.
|
||||
*/
|
||||
protected MessagingTemplate getMessagingTemplate() {
|
||||
@@ -134,18 +131,10 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
|
||||
@Override
|
||||
protected final void onInit() {
|
||||
Assert.state(!(this.outputChannelName != null && this.outputChannel != null),
|
||||
"'outputChannelName' and 'outputChannel' are mutually exclusive.");
|
||||
if (this.getBeanFactory() != null) {
|
||||
this.messagingTemplate.setBeanFactory(getBeanFactory());
|
||||
if (StringUtils.hasText(this.outputChannelName)) {
|
||||
Assert.isNull(this.outputChannel, "'outputChannelName' and 'outputChannel' are mutually exclusive.");
|
||||
try {
|
||||
this.outputChannel = this.getBeanFactory().getBean(this.outputChannelName, MessageChannel.class);
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.outputChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(this.adviceChain)) {
|
||||
ProxyFactory proxyFactory = new ProxyFactory(new AdvisedRequestHandler());
|
||||
@@ -229,7 +218,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
* Send a reply Message. The 'replyChannelHeaderValue' will be considered only if this handler's
|
||||
* 'outputChannel' is <code>null</code>. In that case, the header value must not also be
|
||||
* <code>null</code>, and it must be an instance of either String or {@link MessageChannel}.
|
||||
*
|
||||
* @param replyMessage the reply Message to send
|
||||
* @param replyChannelHeaderValue the 'replyChannel' header value from the original request
|
||||
*/
|
||||
@@ -237,6 +225,22 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("handler '" + this + "' sending reply Message: " + replyMessage);
|
||||
}
|
||||
|
||||
if (this.outputChannelName != null) {
|
||||
synchronized (this) {
|
||||
if (this.outputChannelName != null) {
|
||||
try {
|
||||
this.outputChannel = this.getBeanFactory().getBean(this.outputChannelName, MessageChannel.class);
|
||||
this.outputChannelName = null;
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.outputChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.outputChannel != null) {
|
||||
this.sendMessage(replyMessage, this.outputChannel);
|
||||
}
|
||||
@@ -251,7 +255,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
/**
|
||||
* Send the message to the given channel. The channel must be a String or
|
||||
* {@link MessageChannel} instance, never <code>null</code>.
|
||||
*
|
||||
* @param message The message.
|
||||
* @param channel The channel to which to send the message.
|
||||
*/
|
||||
@@ -279,7 +282,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
|
||||
/**
|
||||
* Subclasses may override this. True by default.
|
||||
*
|
||||
* @return true if the request headers should be copied.
|
||||
*/
|
||||
protected boolean shouldCopyRequestHeaders() {
|
||||
@@ -291,7 +293,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
* value may be a Message, a MessageBuilder, or any plain Object. The base class
|
||||
* will handle the final creation of a reply Message from any of those starting
|
||||
* points. If the return value is null, the Message flow will end here.
|
||||
*
|
||||
* @param requestMessage The request message.
|
||||
* @return The result of handling the message, or {@code null}.
|
||||
*/
|
||||
@@ -318,7 +319,6 @@ public abstract class AbstractReplyProducingMessageHandler extends AbstractMessa
|
||||
return AbstractReplyProducingMessageHandler.this.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.springframework.messaging.MessageDeliveryException;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.core.DestinationResolutionException;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base class for all Message Routers.
|
||||
@@ -62,9 +61,8 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
|
||||
* fails to return any channels. If no default channel is provided and channel
|
||||
* resolution fails to return any channels, the router will throw an
|
||||
* {@link MessageDeliveryException}.
|
||||
*
|
||||
* <p>
|
||||
* If messages shall be ignored (dropped) instead, please provide a {@link NullChannel}.
|
||||
*
|
||||
* @param defaultOutputChannel The default output channel.
|
||||
*/
|
||||
public void setDefaultOutputChannel(MessageChannel defaultOutputChannel) {
|
||||
@@ -72,13 +70,13 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
|
||||
}
|
||||
|
||||
public void setDefaultOutputChannelName(String defaultOutputChannelName) {
|
||||
Assert.hasText(defaultOutputChannelName, "'defaultOutputChannelName' must not be empty");
|
||||
this.defaultOutputChannelName = defaultOutputChannelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the timeout for sending a message to the resolved channel. By default, there is no timeout, meaning the send
|
||||
* will block indefinitely.
|
||||
*
|
||||
* @param timeout The timeout.
|
||||
*/
|
||||
public void setTimeout(long timeout) {
|
||||
@@ -89,7 +87,6 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
|
||||
* Specify whether send failures for one or more of the recipients should be ignored. By default this is
|
||||
* <code>false</code> meaning that an Exception will be thrown whenever a send fails. To override this and suppress
|
||||
* Exceptions, set the value to <code>true</code>.
|
||||
*
|
||||
* @param ignoreSendFailures true to ignore send failures.
|
||||
*/
|
||||
public void setIgnoreSendFailures(boolean ignoreSendFailures) {
|
||||
@@ -101,7 +98,6 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
|
||||
* channels. By default, this value is <code>false</code> meaning that sequence headers will <em>not</em> be
|
||||
* applied. If planning to use an Aggregator downstream with the default correlation and completion strategies, you
|
||||
* should set this flag to <code>true</code>.
|
||||
*
|
||||
* @param applySequence true to apply sequence information.
|
||||
*/
|
||||
public void setApplySequence(boolean applySequence) {
|
||||
@@ -115,7 +111,6 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
|
||||
|
||||
/**
|
||||
* Provides {@link MessagingTemplate} access for subclasses
|
||||
*
|
||||
* @return The messaging template.
|
||||
*/
|
||||
protected MessagingTemplate getMessagingTemplate() {
|
||||
@@ -136,25 +131,16 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
|
||||
@Override
|
||||
protected void onInit() throws Exception {
|
||||
super.onInit();
|
||||
Assert.state(!(this.defaultOutputChannelName != null && this.defaultOutputChannel != null),
|
||||
"'defaultOutputChannelName' and 'defaultOutputChannel' are mutually exclusive.");
|
||||
if (this.getBeanFactory() != null) {
|
||||
this.messagingTemplate.setBeanFactory(this.getBeanFactory());
|
||||
if (StringUtils.hasText(this.defaultOutputChannelName)) {
|
||||
Assert.isNull(this.defaultOutputChannel, "'defaultOutputChannelName' and 'defaultOutputChannel' are mutually exclusive.");
|
||||
try {
|
||||
this.defaultOutputChannel = this.getBeanFactory().getBean(this.defaultOutputChannelName, MessageChannel.class);
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.defaultOutputChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this method to return a Collection of zero or more
|
||||
* MessageChannels to which the given Message should be routed.
|
||||
*
|
||||
* @param message The message.
|
||||
* @return The collection of message channels.
|
||||
*/
|
||||
@@ -168,8 +154,11 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
|
||||
int sequenceSize = results.size();
|
||||
int sequenceNumber = 1;
|
||||
for (MessageChannel channel : results) {
|
||||
final Message<?> messageToSend = (!this.applySequence) ? message : this.getMessageBuilderFactory().fromMessage(message)
|
||||
.pushSequenceDetails(message.getHeaders().getId(), sequenceNumber++, sequenceSize).build();
|
||||
final Message<?> messageToSend =
|
||||
!this.applySequence ? message : (this.getMessageBuilderFactory()
|
||||
.fromMessage(message)
|
||||
.pushSequenceDetails(message.getHeaders().getId(), sequenceNumber++, sequenceSize)
|
||||
.build());
|
||||
if (channel != null) {
|
||||
try {
|
||||
this.messagingTemplate.send(channel, messageToSend);
|
||||
@@ -187,6 +176,21 @@ public abstract class AbstractMessageRouter extends AbstractMessageHandler {
|
||||
}
|
||||
}
|
||||
if (!sent) {
|
||||
if (this.defaultOutputChannelName != null) {
|
||||
synchronized (this) {
|
||||
if (this.defaultOutputChannelName != null) {
|
||||
try {
|
||||
this.defaultOutputChannel = getBeanFactory()
|
||||
.getBean(this.defaultOutputChannelName, MessageChannel.class);
|
||||
this.defaultOutputChannelName = null;
|
||||
}
|
||||
catch (BeansException e) {
|
||||
throw new DestinationResolutionException("Failed to look up MessageChannel with name '"
|
||||
+ this.defaultOutputChannelName + "' in the BeanFactory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.defaultOutputChannel != null) {
|
||||
this.messagingTemplate.send(this.defaultOutputChannel, message);
|
||||
}
|
||||
|
||||
@@ -198,7 +198,6 @@ public class ContentEnricher extends AbstractReplyProducingMessageHandler
|
||||
* object</b>.
|
||||
* <p>
|
||||
* For instance the following SpEL expressions (among others) are possible:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>payload.foo</li>
|
||||
* <li>headers.foobar</li>
|
||||
|
||||
@@ -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.
|
||||
@@ -37,11 +37,8 @@ import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy;
|
||||
import org.springframework.integration.aggregator.SequenceSizeReleaseStrategy;
|
||||
import org.springframework.integration.channel.NullChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.support.channel.BeanFactoryChannelResolver;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.core.DestinationResolver;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
@@ -71,10 +68,8 @@ public class AggregatorAnnotationTests {
|
||||
final String endpointName = "endpointWithCustomizedAnnotation";
|
||||
MessageHandler aggregator = this.getAggregator(context, endpointName);
|
||||
assertTrue(getPropertyValue(aggregator, "releaseStrategy") instanceof SequenceSizeReleaseStrategy);
|
||||
DestinationResolver<MessageChannel> channelResolver = new BeanFactoryChannelResolver(context);
|
||||
assertEquals(channelResolver.resolveDestination("outputChannel"), getPropertyValue(aggregator, "outputChannel"));
|
||||
assertEquals(channelResolver.resolveDestination("discardChannel"), getPropertyValue(aggregator,
|
||||
"discardChannel"));
|
||||
assertEquals("outputChannel", getPropertyValue(aggregator, "outputChannelName"));
|
||||
assertEquals("discardChannel", getPropertyValue(aggregator, "discardChannelName"));
|
||||
assertEquals(98765432l, getPropertyValue(aggregator, "messagingTemplate.sendTimeout"));
|
||||
assertEquals(true, getPropertyValue(aggregator, "sendPartialResultOnExpiry"));
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ public class FilterAnnotationPostProcessorTests {
|
||||
@MessageEndpoint
|
||||
private static class TestFilterWithBooleanPrimitive {
|
||||
|
||||
@Filter(inputChannel="input", outputChannel="output")
|
||||
@Filter(inputChannel = "input", outputChannel = "output")
|
||||
public boolean filter(String s) {
|
||||
return !s.contains("bad");
|
||||
}
|
||||
@@ -207,7 +207,7 @@ public class FilterAnnotationPostProcessorTests {
|
||||
@MessageEndpoint
|
||||
private static class TestFilterWithAdviceDiscardWithin {
|
||||
|
||||
@Filter(inputChannel="input", outputChannel="output", adviceChain="adviceChain")
|
||||
@Filter(inputChannel = "input", outputChannel = "output", adviceChain = "adviceChain")
|
||||
public boolean filter(String s) {
|
||||
return !s.contains("bad");
|
||||
}
|
||||
@@ -216,7 +216,7 @@ public class FilterAnnotationPostProcessorTests {
|
||||
@MessageEndpoint
|
||||
private static class TestFilterWithAdviceDiscardWithinTwice {
|
||||
|
||||
@Filter(inputChannel="input", outputChannel="output", adviceChain={"adviceChain1", "adviceChain2"})
|
||||
@Filter(inputChannel = "input", outputChannel = "output", adviceChain = {"adviceChain1", "adviceChain2"})
|
||||
public boolean filter(String s) {
|
||||
return !s.contains("bad");
|
||||
}
|
||||
@@ -225,8 +225,8 @@ public class FilterAnnotationPostProcessorTests {
|
||||
@MessageEndpoint
|
||||
private static class TestFilterWithAdviceDiscardWithout {
|
||||
|
||||
@Filter(inputChannel="input", outputChannel="output",
|
||||
adviceChain="adviceChain", discardWithinAdvice=false)
|
||||
@Filter(inputChannel = "input", outputChannel = "output",
|
||||
adviceChain = "adviceChain", discardWithinAdvice = "false")
|
||||
public boolean filter(String s) {
|
||||
return !s.contains("bad");
|
||||
}
|
||||
@@ -235,7 +235,7 @@ public class FilterAnnotationPostProcessorTests {
|
||||
@MessageEndpoint
|
||||
private static class TestFilterWithBooleanWrapperClass {
|
||||
|
||||
@Filter(inputChannel="input", outputChannel="output")
|
||||
@Filter(inputChannel = "input", outputChannel = "output")
|
||||
public Boolean filter(String s) {
|
||||
return !s.contains("bad");
|
||||
}
|
||||
@@ -245,7 +245,7 @@ public class FilterAnnotationPostProcessorTests {
|
||||
@MessageEndpoint
|
||||
private static class TestFilterWithStringReturnType {
|
||||
|
||||
@Filter(inputChannel="input", outputChannel="output")
|
||||
@Filter(inputChannel = "input", outputChannel = "output")
|
||||
public String filter(String s) {
|
||||
return s;
|
||||
}
|
||||
@@ -255,7 +255,7 @@ public class FilterAnnotationPostProcessorTests {
|
||||
@MessageEndpoint
|
||||
private static class TestFilterWithVoidReturnType {
|
||||
|
||||
@Filter(inputChannel="input", outputChannel="output")
|
||||
@Filter(inputChannel = "input", outputChannel = "output")
|
||||
public void filter(String s) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
<enricher id="enricher" input-channel="input"
|
||||
request-channel="requests1" request-timeout="1234"
|
||||
reply-timeout="9876" reply-channel="replies"
|
||||
reply-timeout="0" reply-channel="replies"
|
||||
order="99" should-clone-payload="true" output-channel="output">
|
||||
<property name="name" expression="payload.sourceName" null-result-expression="'Could not determine the name'"/>
|
||||
<property name="age" value="42" null-result-expression="'11'"/>
|
||||
|
||||
@@ -17,7 +17,15 @@
|
||||
package org.springframework.integration.configuration;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -402,19 +410,19 @@ public class EnableIntegrationTests {
|
||||
assertFalse(TestUtils.getPropertyValue(consumer, "autoStartup", Boolean.class));
|
||||
assertEquals(23, TestUtils.getPropertyValue(consumer, "phase"));
|
||||
assertSame(context.getBean("annInput"), TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertSame(context.getBean("annOutput"), TestUtils.getPropertyValue(consumer, "handler.outputChannel"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.outputChannelName"));
|
||||
assertSame(context.getBean("annAdvice"), TestUtils.getPropertyValue(consumer,
|
||||
"handler.adviceChain", List.class).get(0));
|
||||
assertEquals(1000L, TestUtils.getPropertyValue(consumer, "trigger.period"));
|
||||
|
||||
consumer = this.context.getBean(
|
||||
"enableIntegrationTests.AnnotationTestService.annCount1.serviceActivator",
|
||||
PollingConsumer.class);
|
||||
"enableIntegrationTests.AnnotationTestService.annCount1.serviceActivator",
|
||||
PollingConsumer.class);
|
||||
consumer.stop();
|
||||
assertTrue(TestUtils.getPropertyValue(consumer, "autoStartup", Boolean.class));
|
||||
assertEquals(23, TestUtils.getPropertyValue(consumer, "phase"));
|
||||
assertSame(context.getBean("annInput1"), TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertSame(context.getBean("annOutput"), TestUtils.getPropertyValue(consumer, "handler.outputChannel"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.outputChannelName"));
|
||||
assertSame(context.getBean("annAdvice1"), TestUtils.getPropertyValue(consumer,
|
||||
"handler.adviceChain", List.class).get(0));
|
||||
assertEquals(2000L, TestUtils.getPropertyValue(consumer, "trigger.period"));
|
||||
@@ -425,7 +433,7 @@ public class EnableIntegrationTests {
|
||||
assertFalse(TestUtils.getPropertyValue(consumer, "autoStartup", Boolean.class));
|
||||
assertEquals(23, TestUtils.getPropertyValue(consumer, "phase"));
|
||||
assertSame(context.getBean("annInput"), TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertSame(context.getBean("annOutput"), TestUtils.getPropertyValue(consumer, "handler.outputChannel"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.outputChannelName"));
|
||||
assertSame(context.getBean("annAdvice"), TestUtils.getPropertyValue(consumer,
|
||||
"handler.adviceChain", List.class).get(0));
|
||||
assertEquals(1000L, TestUtils.getPropertyValue(consumer, "trigger.period"));
|
||||
@@ -437,7 +445,7 @@ public class EnableIntegrationTests {
|
||||
assertFalse(TestUtils.getPropertyValue(consumer, "autoStartup", Boolean.class));
|
||||
assertEquals(23, TestUtils.getPropertyValue(consumer, "phase"));
|
||||
assertSame(context.getBean("annInput3"), TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertSame(context.getBean("annOutput"), TestUtils.getPropertyValue(consumer, "handler.outputChannel"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.outputChannelName"));
|
||||
assertSame(context.getBean("annAdvice"), TestUtils.getPropertyValue(consumer,
|
||||
"handler.adviceChain", List.class).get(0));
|
||||
assertEquals(1000L, TestUtils.getPropertyValue(consumer, "trigger.period"));
|
||||
@@ -448,8 +456,8 @@ public class EnableIntegrationTests {
|
||||
assertFalse(TestUtils.getPropertyValue(consumer, "autoStartup", Boolean.class));
|
||||
assertEquals(23, TestUtils.getPropertyValue(consumer, "phase"));
|
||||
assertSame(context.getBean("annInput"), TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertSame(context.getBean("annOutput"), TestUtils.getPropertyValue(consumer, "handler.outputChannel"));
|
||||
assertSame(context.getBean("annOutput"), TestUtils.getPropertyValue(consumer, "handler.discardChannel"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.outputChannelName"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.discardChannelName"));
|
||||
assertEquals(1000L, TestUtils.getPropertyValue(consumer, "trigger.period"));
|
||||
assertEquals(1000L, TestUtils.getPropertyValue(consumer, "handler.messagingTemplate.sendTimeout"));
|
||||
assertFalse(TestUtils.getPropertyValue(consumer, "handler.sendPartialResultOnExpiry", Boolean.class));
|
||||
@@ -460,8 +468,8 @@ public class EnableIntegrationTests {
|
||||
assertFalse(TestUtils.getPropertyValue(consumer, "autoStartup", Boolean.class));
|
||||
assertEquals(23, TestUtils.getPropertyValue(consumer, "phase"));
|
||||
assertSame(context.getBean("annInput"), TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertSame(context.getBean("annOutput"), TestUtils.getPropertyValue(consumer, "handler.outputChannel"));
|
||||
assertSame(context.getBean("annOutput"), TestUtils.getPropertyValue(consumer, "handler.discardChannel"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.outputChannelName"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.discardChannelName"));
|
||||
assertEquals(1000L, TestUtils.getPropertyValue(consumer, "trigger.period"));
|
||||
assertEquals(75L, TestUtils.getPropertyValue(consumer, "handler.messagingTemplate.sendTimeout"));
|
||||
assertTrue(TestUtils.getPropertyValue(consumer, "handler.sendPartialResultOnExpiry", Boolean.class));
|
||||
@@ -795,8 +803,8 @@ public class EnableIntegrationTests {
|
||||
return new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
asyncAnnotationProcessLatch().countDown();
|
||||
asyncAnnotationProcessThread().set(Thread.currentThread());
|
||||
asyncAnnotationProcessLatch().countDown();
|
||||
asyncAnnotationProcessThread().set(Thread.currentThread());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -996,7 +1004,7 @@ public class EnableIntegrationTests {
|
||||
}
|
||||
|
||||
@MyServiceActivator1(inputChannel = "annInput1", autoStartup = "true",
|
||||
adviceChain = { "annAdvice1" }, poller = @Poller(fixedRate = "2000") )
|
||||
adviceChain = {"annAdvice1"}, poller = @Poller(fixedRate = "2000"))
|
||||
public Integer annCount1() {
|
||||
return 0;
|
||||
}
|
||||
@@ -1074,11 +1082,11 @@ public class EnableIntegrationTests {
|
||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ServiceActivator(autoStartup = "false",
|
||||
phase = "23",
|
||||
inputChannel = "annInput",
|
||||
outputChannel = "annOutput",
|
||||
adviceChain = { "annAdvice" },
|
||||
poller = @Poller(fixedDelay = "1000"))
|
||||
phase = "23",
|
||||
inputChannel = "annInput",
|
||||
outputChannel = "annOutput",
|
||||
adviceChain = {"annAdvice"},
|
||||
poller = @Poller(fixedDelay = "1000"))
|
||||
public static @interface MyServiceActivator {
|
||||
|
||||
String inputChannel() default "";
|
||||
@@ -1181,22 +1189,22 @@ public class EnableIntegrationTests {
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@ServiceActivator(autoStartup = "false",
|
||||
phase = "23",
|
||||
inputChannel = "annInput",
|
||||
outputChannel = "annOutput",
|
||||
adviceChain = { "annAdvice" },
|
||||
poller = @Poller(fixedDelay = "1000"))
|
||||
phase = "23",
|
||||
inputChannel = "annInput",
|
||||
outputChannel = "annOutput",
|
||||
adviceChain = {"annAdvice"},
|
||||
poller = @Poller(fixedDelay = "1000"))
|
||||
public static @interface MyServiceActivatorNoLocalAtts {
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Aggregator(autoStartup = "false",
|
||||
phase = "23",
|
||||
inputChannel = "annInput",
|
||||
outputChannel = "annOutput",
|
||||
discardChannel = "annOutput",
|
||||
poller = @Poller(fixedDelay = "1000"))
|
||||
phase = "23",
|
||||
inputChannel = "annInput",
|
||||
outputChannel = "annOutput",
|
||||
discardChannel = "annOutput",
|
||||
poller = @Poller(fixedDelay = "1000"))
|
||||
public static @interface MyAggregator {
|
||||
|
||||
String inputChannel() default "";
|
||||
@@ -1219,13 +1227,13 @@ public class EnableIntegrationTests {
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Aggregator(autoStartup = "false",
|
||||
phase = "23",
|
||||
inputChannel = "annInput",
|
||||
outputChannel = "annOutput",
|
||||
discardChannel = "annOutput",
|
||||
sendPartialResultsOnExpiry = false,
|
||||
sendTimeout = 1000L,
|
||||
poller = @Poller(fixedDelay = "1000"))
|
||||
phase = "23",
|
||||
inputChannel = "annInput",
|
||||
outputChannel = "annOutput",
|
||||
discardChannel = "annOutput",
|
||||
sendPartialResultsOnExpiry = false,
|
||||
sendTimeout = 1000L,
|
||||
poller = @Poller(fixedDelay = "1000"))
|
||||
public static @interface MyAggregatorDefaultOverrideDefaults {
|
||||
|
||||
boolean sendPartialResultsOnExpiry() default true;
|
||||
|
||||
@@ -16,8 +16,12 @@
|
||||
|
||||
package org.springframework.integration.router;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -333,7 +337,7 @@ public class RecipientListRouterTests {
|
||||
assertNotNull(result1a);
|
||||
assertNotNull(result1b);
|
||||
assertEquals("test", result1a.getPayload());
|
||||
assertEquals(1,new IntegrationMessageHeaderAccessor(result1a).getSequenceNumber().intValue());
|
||||
assertEquals(1, new IntegrationMessageHeaderAccessor(result1a).getSequenceNumber().intValue());
|
||||
assertEquals(2, new IntegrationMessageHeaderAccessor(result1a).getSequenceSize().intValue());
|
||||
assertEquals(message.getHeaders().getId(), new IntegrationMessageHeaderAccessor(result1a).getCorrelationId());
|
||||
assertEquals("test", result1b.getPayload());
|
||||
@@ -426,6 +430,8 @@ public class RecipientListRouterTests {
|
||||
router.setBeanFactory(beanFactory);
|
||||
router.afterPropertiesSet();
|
||||
|
||||
router.handleMessage(new GenericMessage<String>("foo"));
|
||||
|
||||
assertSame(defaultChannel, TestUtils.getPropertyValue(router, "defaultOutputChannel"));
|
||||
Mockito.verify(beanFactory).getBean(Mockito.eq("defaultChannel"), Mockito.eq(MessageChannel.class));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user