INT-3319 Fix BeanFactory Propagation

JIRA: https://jira.spring.io/browse/INT-3319

The `MessageBuilderFactory` abstraction relies on the bean factory
being propagated to all classes that create messages.

Some classes were missed in the initial PR.
This commit is contained in:
Gary Russell
2014-03-11 16:24:29 -04:00
committed by Artem Bilan
parent 1c9bcaccee
commit 75af72a77c
39 changed files with 364 additions and 179 deletions

View File

@@ -21,7 +21,11 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.integration.IntegrationMessageHeaderAccessor;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.store.MessageGroup;
import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
import org.springframework.integration.support.DefaultMessageBuilderFactory;
@@ -39,15 +43,16 @@ import org.springframework.util.Assert;
* @author Dave Syer
* @since 2.0
*/
public abstract class AbstractAggregatingMessageGroupProcessor implements MessageGroupProcessor {
public abstract class AbstractAggregatingMessageGroupProcessor implements MessageGroupProcessor,
BeanFactoryAware {
private final Log logger = LogFactory.getLog(this.getClass());
private volatile MessageBuilderFactory messageBuilderFactory = new DefaultMessageBuilderFactory();
public void setMessageBuilderFactory(MessageBuilderFactory messageBuilderFactory) {
Assert.notNull(messageBuilderFactory, "'messageBuilderFactory' cannot be null");
this.messageBuilderFactory = messageBuilderFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.messageBuilderFactory = IntegrationContextUtils.getMessageBuilderFactory(beanFactory);
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 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.
@@ -30,6 +30,7 @@ import org.springframework.integration.store.MessageGroup;
*
* @author Alex Peters
* @author Dave Syer
* @author Gary Russell
*/
public class ExpressionEvaluatingMessageGroupProcessor extends AbstractAggregatingMessageGroupProcessor implements BeanFactoryAware {
@@ -40,7 +41,9 @@ public class ExpressionEvaluatingMessageGroupProcessor extends AbstractAggregati
processor = new ExpressionEvaluatingMessageListProcessor(expression);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
processor.setBeanFactory(beanFactory);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 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.
@@ -22,16 +22,17 @@ import java.util.Map;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.messaging.Message;
import org.springframework.integration.annotation.Aggregator;
import org.springframework.integration.store.MessageGroup;
import org.springframework.messaging.Message;
/**
* MessageGroupProcessor that serves as an adapter for the invocation of a POJO method.
*
*
* @author Iwein Fuld
* @author Mark Fisher
* @author Dave Syer
* @author Gary Russell
* @since 2.0
*/
public class MethodInvokingMessageGroupProcessor extends AbstractAggregatingMessageGroupProcessor {
@@ -41,7 +42,7 @@ public class MethodInvokingMessageGroupProcessor extends AbstractAggregatingMess
/**
* Creates a wrapper around the object passed in. This constructor will look for a method that can process
* a list of messages.
*
*
* @param target the object to wrap
*/
public MethodInvokingMessageGroupProcessor(Object target) {
@@ -51,7 +52,7 @@ public class MethodInvokingMessageGroupProcessor extends AbstractAggregatingMess
/**
* Creates a wrapper around the object passed in. This constructor will look for a named method specifically and
* fail when it cannot find a method with the given name.
*
*
* @param target the object to wrap
* @param methodName the name of the method to invoke
*/
@@ -61,19 +62,21 @@ public class MethodInvokingMessageGroupProcessor extends AbstractAggregatingMess
/**
* Creates a wrapper around the object passed in.
*
*
* @param target the object to wrap
* @param method the method to invoke
*/
public MethodInvokingMessageGroupProcessor(Object target, Method method) {
this.processor = new MethodInvokingMessageListProcessor<Object>(target, method);
}
public void setConversionService(ConversionService conversionService) {
processor.setConversionService(conversionService);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
processor.setBeanFactory(beanFactory);
}

View File

@@ -164,6 +164,7 @@ public class PublishSubscribeChannel extends AbstractSubscribableChannel {
Integer maxSubscribers = this.getIntegrationProperty(IntegrationProperties.CHANNELS_MAX_BROADCAST_SUBSCRIBERS, Integer.class);
this.setMaxSubscribers(maxSubscribers);
}
this.dispatcher.setBeanFactory(this.getBeanFactory());
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 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.
@@ -20,9 +20,9 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicReference;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.messaging.MessageChannel;
import org.springframework.integration.aggregator.AggregatingMessageHandler;
import org.springframework.integration.aggregator.MethodInvokingCorrelationStrategy;
import org.springframework.integration.aggregator.MethodInvokingMessageGroupProcessor;
@@ -30,8 +30,9 @@ import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy;
import org.springframework.integration.annotation.Aggregator;
import org.springframework.integration.annotation.CorrelationStrategy;
import org.springframework.integration.annotation.ReleaseStrategy;
import org.springframework.messaging.MessageHandler;
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.ReflectionUtils;
import org.springframework.util.StringUtils;
@@ -44,14 +45,18 @@ import org.springframework.util.StringUtils;
*/
public class AggregatorAnnotationPostProcessor extends AbstractMethodAnnotationPostProcessor<Aggregator> {
private final BeanFactory beanFactory;
public AggregatorAnnotationPostProcessor(ListableBeanFactory beanFactory) {
super(beanFactory);
this.beanFactory = beanFactory;
}
@Override
protected MessageHandler createHandler(Object bean, Method method, Aggregator annotation) {
MethodInvokingMessageGroupProcessor processor = new MethodInvokingMessageGroupProcessor(bean, method);
processor.setBeanFactory(this.beanFactory);
MethodInvokingReleaseStrategy releaseStrategy = getReleaseStrategy(bean);
MethodInvokingCorrelationStrategy correlationStrategy = getCorrelationStrategy(bean);
AggregatingMessageHandler handler = new AggregatingMessageHandler(processor, new SimpleMessageStore(), correlationStrategy, releaseStrategy);
@@ -73,29 +78,31 @@ public class AggregatorAnnotationPostProcessor extends AbstractMethodAnnotationP
}
private MethodInvokingReleaseStrategy getReleaseStrategy(final Object bean) {
final AtomicReference<MethodInvokingReleaseStrategy> reference = new AtomicReference<MethodInvokingReleaseStrategy>();
final AtomicReference<MethodInvokingReleaseStrategy> reference = new AtomicReference<MethodInvokingReleaseStrategy>();
ReflectionUtils.doWithMethods(bean.getClass(), new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Annotation annotation = AnnotationUtils.getAnnotation(method, ReleaseStrategy.class);
if (annotation != null) {
reference.set(new MethodInvokingReleaseStrategy(bean, method));
reference.set(new MethodInvokingReleaseStrategy(bean, method));
}
}
});
return reference.get();
return reference.get();
}
private MethodInvokingCorrelationStrategy getCorrelationStrategy(final Object bean) {
final AtomicReference<MethodInvokingCorrelationStrategy> reference = new AtomicReference<MethodInvokingCorrelationStrategy>();
ReflectionUtils.doWithMethods(bean.getClass(), new ReflectionUtils.MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Annotation annotation = AnnotationUtils.getAnnotation(method, CorrelationStrategy.class);
if (annotation != null) {
reference.set(new MethodInvokingCorrelationStrategy(bean, method));
}
}
});
return reference.get();
}
private MethodInvokingCorrelationStrategy getCorrelationStrategy(final Object bean) {
final AtomicReference<MethodInvokingCorrelationStrategy> reference = new AtomicReference<MethodInvokingCorrelationStrategy>();
ReflectionUtils.doWithMethods(bean.getClass(), new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Annotation annotation = AnnotationUtils.getAnnotation(method, CorrelationStrategy.class);
if (annotation != null) {
reference.set(new MethodInvokingCorrelationStrategy(bean, method));
}
}
});
return reference.get();
}
}

View File

@@ -23,8 +23,6 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.integration.support.DefaultMessageBuilderFactory;
import org.springframework.integration.support.MessageBuilderFactory;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.util.Assert;
@@ -55,7 +53,6 @@ public abstract class AbstractDispatcher implements MessageDispatcher {
private volatile MessageHandler theOneHandler;
private volatile MessageBuilderFactory messageBuilderFactory = new DefaultMessageBuilderFactory();
/**
* Set the maximum subscribers allowed by this dispatcher.
* @param maxSubscribers The maximum number of subscribers allowed.
@@ -74,15 +71,6 @@ public abstract class AbstractDispatcher implements MessageDispatcher {
return handlers.asUnmodifiableSet();
}
protected MessageBuilderFactory getMessageBuilderFactory() {
return messageBuilderFactory;
}
public void setMessageBuilderFactory(MessageBuilderFactory messageBuilderFactory) {
Assert.notNull(messageBuilderFactory, "'messageBuilderFactory' cannot be null");
this.messageBuilderFactory = messageBuilderFactory;
}
/**
* Add the handler to the internal Set.
*

View File

@@ -19,7 +19,13 @@ package org.springframework.integration.dispatcher;
import java.util.Collection;
import java.util.concurrent.Executor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.integration.MessageDispatchingException;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.support.DefaultMessageBuilderFactory;
import org.springframework.integration.support.MessageBuilderFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
@@ -39,7 +45,7 @@ import org.springframework.messaging.MessagingException;
* @author Gary Russell
* @author Oleg Zhurakousky
*/
public class BroadcastingDispatcher extends AbstractDispatcher {
public class BroadcastingDispatcher extends AbstractDispatcher implements BeanFactoryAware {
private final boolean requireSubscribers;
@@ -51,6 +57,9 @@ public class BroadcastingDispatcher extends AbstractDispatcher {
private volatile int minSubscribers;
private volatile MessageBuilderFactory messageBuilderFactory = new DefaultMessageBuilderFactory();
public BroadcastingDispatcher() {
this(null, false);
}
@@ -103,6 +112,11 @@ public class BroadcastingDispatcher extends AbstractDispatcher {
this.minSubscribers = minSubscribers;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.messageBuilderFactory = IntegrationContextUtils.getMessageBuilderFactory(beanFactory);
}
@Override
public boolean dispatch(Message<?> message) {
int dispatched = 0;
@@ -113,7 +127,7 @@ public class BroadcastingDispatcher extends AbstractDispatcher {
}
int sequenceSize = handlers.size();
for (final MessageHandler handler : handlers) {
final Message<?> messageToSend = (!this.applySequence) ? message : this.getMessageBuilderFactory().fromMessage(message)
final Message<?> messageToSend = (!this.applySequence) ? message : this.messageBuilderFactory.fromMessage(message)
.pushSequenceDetails(message.getHeaders().getId(), sequenceNumber++, sequenceSize).build();
if (this.executor != null) {
this.executor.execute(new Runnable() {

View File

@@ -180,6 +180,7 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint implement
if (this.requestMapper instanceof DefaultRequestMapper) {
((DefaultRequestMapper) this.requestMapper).setMessageBuilderFactory(this.getMessageBuilderFactory());
}
this.messageConverter.setBeanFactory(this.getBeanFactory());
}
this.initialized = true;
}

View File

@@ -16,6 +16,10 @@
package org.springframework.integration.support.converter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.mapping.InboundMessageMapper;
import org.springframework.integration.mapping.OutboundMessageMapper;
import org.springframework.integration.support.DefaultMessageBuilderFactory;
@@ -31,7 +35,7 @@ import org.springframework.messaging.converter.MessageConverter;
* @since 2.0
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class SimpleMessageConverter implements MessageConverter {
public class SimpleMessageConverter implements MessageConverter, BeanFactoryAware {
private volatile InboundMessageMapper inboundMessageMapper;
@@ -67,8 +71,9 @@ public class SimpleMessageConverter implements MessageConverter {
this.outboundMessageMapper = (outboundMessageMapper != null) ? outboundMessageMapper : new DefaultOutboundMessageMapper();
}
public final void setMessageBuilderFactory(MessageBuilderFactory messageBuilderFactory) {
this.messageBuilderFactory = messageBuilderFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.messageBuilderFactory = IntegrationContextUtils.getMessageBuilderFactory(beanFactory);
}
@Override

View File

@@ -18,10 +18,13 @@ package org.springframework.integration.support.json;
import java.lang.reflect.Type;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.support.DefaultMessageBuilderFactory;
import org.springframework.integration.support.MessageBuilderFactory;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
/**
* Base {@link JsonInboundMessageMapper.JsonMessageParser} implementation for Jackson processors.
@@ -30,7 +33,8 @@ import org.springframework.util.Assert;
* @since 3.0
*
*/
abstract class AbstractJacksonJsonMessageParser<P> implements JsonInboundMessageMapper.JsonMessageParser<P> {
abstract class AbstractJacksonJsonMessageParser<P> implements JsonInboundMessageMapper.JsonMessageParser<P>,
BeanFactoryAware {
private final JsonObjectMapper<?, P> objectMapper;
@@ -42,9 +46,9 @@ abstract class AbstractJacksonJsonMessageParser<P> implements JsonInboundMessage
this.objectMapper = objectMapper;
}
public void setMessageBuilderFactory(MessageBuilderFactory messageBuilderFactory) {
Assert.notNull(messageBuilderFactory, "'messageBuilderFactory' cannot be null");
this.messageBuilderFactory = messageBuilderFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.messageBuilderFactory = IntegrationContextUtils.getMessageBuilderFactory(beanFactory);
}
protected MessageBuilderFactory getMessageBuilderFactory() {

View File

@@ -32,7 +32,6 @@ import org.springframework.integration.support.DefaultMessageBuilderFactory;
import org.springframework.integration.support.MessageBuilderFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.util.Assert;
/**
* @author Mark Fisher
@@ -60,6 +59,7 @@ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware, I
/**
* Specify a BeanFactory in order to enable resolution via <code>@beanName</code> in the expression.
*/
@Override
public void setBeanFactory(final BeanFactory beanFactory) {
if (beanFactory != null) {
this.beanFactory = beanFactory;
@@ -67,6 +67,7 @@ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware, I
if (this.evaluationContext != null && this.evaluationContext.getBeanResolver() == null) {
this.evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory));
}
this.messageBuilderFactory = IntegrationContextUtils.getMessageBuilderFactory(beanFactory);
}
}
@@ -76,11 +77,6 @@ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware, I
}
}
public void setMessageBuilderFactory(MessageBuilderFactory messageBuilderFactory) {
Assert.notNull(messageBuilderFactory, "'messageBuilderFactory' cannot be null");
this.messageBuilderFactory = messageBuilderFactory;
}
protected MessageBuilderFactory getMessageBuilderFactory() {
if (this.messageBuilderFactory == null) {
this.messageBuilderFactory = new DefaultMessageBuilderFactory();
@@ -92,7 +88,7 @@ public abstract class AbstractExpressionEvaluator implements BeanFactoryAware, I
public void afterPropertiesSet() throws Exception {
getEvaluationContext();
if (this.messageBuilderFactory == null) {
this.messageBuilderFactory = IntegrationContextUtils.getMessageBuilderFactory(beanFactory);
this.messageBuilderFactory = IntegrationContextUtils.getMessageBuilderFactory(this.beanFactory);
}
}

View File

@@ -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,7 +37,6 @@ import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.integration.MessageRejectedException;
import org.springframework.integration.aggregator.AggregatingMessageHandler;
import org.springframework.integration.aggregator.CorrelationStrategy;
@@ -46,6 +45,7 @@ import org.springframework.integration.aggregator.ExpressionEvaluatingReleaseStr
import org.springframework.integration.aggregator.MethodInvokingMessageGroupProcessor;
import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy;
import org.springframework.integration.aggregator.ReleaseStrategy;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
@@ -53,6 +53,7 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageDeliveryException;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHandlingException;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.SubscribableChannel;
@@ -63,6 +64,7 @@ import org.springframework.messaging.SubscribableChannel;
* @author Oleg Zhurakousky
* @author Artem Bilan
* @author Gunnar Hillert
* @author Gary Russell
*/
public class AggregatorParserTests {
@@ -88,6 +90,10 @@ public class AggregatorParserTests {
.size());
Message<?> aggregatedMessage = aggregatorBean.getAggregatedMessages().get("id1");
assertEquals("The aggregated message payload is not correct", "123456789", aggregatedMessage.getPayload());
Object mbf = context.getBean(IntegrationContextUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME);
Object handler = context.getBean("aggregatorWithReference.handler");
assertSame(mbf, TestUtils.getPropertyValue(handler, "outputProcessor.messageBuilderFactory"));
assertSame(mbf, TestUtils.getPropertyValue(handler, "outputProcessor.processor.messageBuilderFactory"));
}
@Test
@@ -96,6 +102,7 @@ public class AggregatorParserTests {
SubscribableChannel outputChannel = (SubscribableChannel) context.getBean("aggregatorWithExpressionsOutput");
final AtomicReference<Message<?>> aggregatedMessage = new AtomicReference<Message<?>>();
outputChannel.subscribe(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessageRejectedException, MessageHandlingException,
MessageDeliveryException {
aggregatedMessage.set(message);
@@ -110,6 +117,10 @@ public class AggregatorParserTests {
}
assertEquals("The aggregated message payload is not correct", "[123]", aggregatedMessage.get().getPayload()
.toString());
Object mbf = context.getBean(IntegrationContextUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME);
Object handler = context.getBean("aggregatorWithExpressions.handler");
assertSame(mbf, TestUtils.getPropertyValue(handler, "outputProcessor.messageBuilderFactory"));
assertSame(mbf, TestUtils.getPropertyValue(handler, "outputProcessor.processor.messageBuilderFactory"));
}
@Test
@@ -158,6 +169,10 @@ public class AggregatorParserTests {
PollableChannel outputChannel = (PollableChannel) context.getBean("outputChannel");
Message<?> response = outputChannel.receive(10);
Assert.assertEquals(6l, response.getPayload());
Object mbf = context.getBean(IntegrationContextUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME);
Object handler = context.getBean("aggregatorWithReferenceAndMethod.handler");
assertSame(mbf, TestUtils.getPropertyValue(handler, "outputProcessor.messageBuilderFactory"));
assertSame(mbf, TestUtils.getPropertyValue(handler, "outputProcessor.processor.messageBuilderFactory"));
}
@Test(expected = BeanCreationException.class)
@@ -230,6 +245,8 @@ public class AggregatorParserTests {
EventDrivenConsumer aggregatorConsumer = (EventDrivenConsumer) context.getBean("aggregatorWithExpressionsAndPojoAggregator");
AggregatingMessageHandler aggregatingMessageHandler = (AggregatingMessageHandler) TestUtils.getPropertyValue(aggregatorConsumer, "handler");
MethodInvokingMessageGroupProcessor messageGroupProcessor = (MethodInvokingMessageGroupProcessor) TestUtils.getPropertyValue(aggregatingMessageHandler, "outputProcessor");
Object mbf = context.getBean(IntegrationContextUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME);
assertSame(mbf, TestUtils.getPropertyValue(messageGroupProcessor, "messageBuilderFactory"));
Object messageGroupProcessorTargetObject = TestUtils.getPropertyValue(messageGroupProcessor, "processor.delegate.targetObject");
assertSame(context.getBean("aggregatorBean"), messageGroupProcessorTargetObject);
ReleaseStrategy releaseStrategy = (ReleaseStrategy) TestUtils.getPropertyValue(aggregatingMessageHandler, "releaseStrategy");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 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.
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.Executor;
@@ -29,12 +30,14 @@ import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.dispatcher.BroadcastingDispatcher;
import org.springframework.integration.util.ErrorHandlingTaskExecutor;
import org.springframework.util.ErrorHandler;
/**
* @author Mark Fisher
* @author Gary Russell
*/
public class PublishSubscribeChannelParserTests {
@@ -51,6 +54,9 @@ public class PublishSubscribeChannelParserTests {
assertNull(dispatcherAccessor.getPropertyValue("executor"));
assertFalse((Boolean) dispatcherAccessor.getPropertyValue("ignoreFailures"));
assertFalse((Boolean) dispatcherAccessor.getPropertyValue("applySequence"));
Object mbf = context.getBean(IntegrationContextUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME);
assertSame(mbf, dispatcherAccessor.getPropertyValue("messageBuilderFactory"));
context.close();
}
@Test
@@ -63,6 +69,7 @@ public class PublishSubscribeChannelParserTests {
BroadcastingDispatcher dispatcher = (BroadcastingDispatcher)
accessor.getPropertyValue("dispatcher");
assertTrue((Boolean) new DirectFieldAccessor(dispatcher).getPropertyValue("ignoreFailures"));
context.close();
}
@Test
@@ -75,6 +82,7 @@ public class PublishSubscribeChannelParserTests {
BroadcastingDispatcher dispatcher = (BroadcastingDispatcher)
accessor.getPropertyValue("dispatcher");
assertTrue((Boolean) new DirectFieldAccessor(dispatcher).getPropertyValue("applySequence"));
context.close();
}
@Test
@@ -93,6 +101,7 @@ public class PublishSubscribeChannelParserTests {
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
Executor innerExecutor = (Executor) executorAccessor.getPropertyValue("executor");
assertEquals(context.getBean("pool"), innerExecutor);
context.close();
}
@Test
@@ -112,6 +121,7 @@ public class PublishSubscribeChannelParserTests {
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
Executor innerExecutor = (Executor) executorAccessor.getPropertyValue("executor");
assertEquals(context.getBean("pool"), innerExecutor);
context.close();
}
@Test
@@ -131,6 +141,7 @@ public class PublishSubscribeChannelParserTests {
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
Executor innerExecutor = (Executor) executorAccessor.getPropertyValue("executor");
assertEquals(context.getBean("pool"), innerExecutor);
context.close();
}
@Test
@@ -143,6 +154,7 @@ public class PublishSubscribeChannelParserTests {
ErrorHandler errorHandler = (ErrorHandler) accessor.getPropertyValue("errorHandler");
assertNotNull(errorHandler);
assertEquals(context.getBean("testErrorHandler"), errorHandler);
context.close();
}
}

View File

@@ -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.
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
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.mockito.Mockito.mock;
@@ -28,6 +29,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.hamcrest.Matchers;
@@ -35,12 +37,14 @@ import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
@@ -55,7 +59,7 @@ public class GatewayInterfaceTests {
@Test
public void testWithServiceSuperclassAnnotatedMethod() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelFoo", DirectChannel.class);
final Method fooMethod = Foo.class.getMethod("foo", String.class);
final AtomicBoolean called = new AtomicBoolean();
@@ -76,11 +80,16 @@ public class GatewayInterfaceTests {
Bar bar = ac.getBean(Bar.class);
bar.foo("hello");
assertTrue(called.get());
Map<?,?> gateways = TestUtils.getPropertyValue(ac.getBean("&sampleGateway"), "gatewayMap", Map.class);
Object mbf = ac.getBean(IntegrationContextUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME);
assertSame(mbf, TestUtils.getPropertyValue(gateways.values().iterator().next(),
"messageConverter.messageBuilderFactory"));
ac.close();
}
@Test
public void testWithServiceSuperclassAnnotatedMethodOverridePE() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests2-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests2-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelFoo", DirectChannel.class);
final Method fooMethod = Foo.class.getMethod("foo", String.class);
final AtomicBoolean called = new AtomicBoolean();
@@ -101,22 +110,24 @@ public class GatewayInterfaceTests {
Bar bar = ac.getBean(Bar.class);
bar.foo("hello");
assertTrue(called.get());
ac.close();
}
@Test
public void testWithServiceAnnotatedMethod() {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelBar", DirectChannel.class);
MessageHandler handler = mock(MessageHandler.class);
channel.subscribe(handler);
Bar bar = ac.getBean(Bar.class);
bar.bar("hello");
verify(handler, times(1)).handleMessage(Mockito.any(Message.class));
ac.close();
}
@Test
public void testWithServiceSuperclassUnAnnotatedMethod() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
final Method bazMethod = Foo.class.getMethod("baz", String.class);
final AtomicBoolean called = new AtomicBoolean();
@@ -137,11 +148,12 @@ public class GatewayInterfaceTests {
Bar bar = ac.getBean(Bar.class);
bar.baz("hello");
assertTrue(called.get());
ac.close();
}
@Test
public void testWithServiceUnAnnotatedMethodGlobalHeaderDoesntOverride() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
final Method quxMethod = Bar.class.getMethod("qux", String.class, String.class);
final AtomicBoolean called = new AtomicBoolean();
@@ -162,55 +174,60 @@ public class GatewayInterfaceTests {
Bar bar = ac.getBean(Bar.class);
bar.qux("hello", "arg1");
assertTrue(called.get());
ac.close();
}
@Test
public void testWithServiceCastAsSuperclassAnnotatedMethod() {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelFoo", DirectChannel.class);
MessageHandler handler = mock(MessageHandler.class);
channel.subscribe(handler);
Foo foo = ac.getBean(Foo.class);
foo.foo("hello");
verify(handler, times(1)).handleMessage(Mockito.any(Message.class));
ac.close();
}
@Test
public void testWithServiceCastAsSuperclassUnAnnotatedMethod() {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
MessageHandler handler = mock(MessageHandler.class);
channel.subscribe(handler);
Foo foo = ac.getBean(Foo.class);
foo.baz("hello");
verify(handler, times(1)).handleMessage(Mockito.any(Message.class));
ac.close();
}
@Test
public void testWithServiceHashcode() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
MessageHandler handler = mock(MessageHandler.class);
channel.subscribe(handler);
Bar bar = ac.getBean(Bar.class);
assertEquals(bar.hashCode(), ac.getBean(Bar.class).hashCode());
verify(handler, times(0)).handleMessage(Mockito.any(Message.class));
ac.close();
}
@Test
public void testWithServiceToString() {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
MessageHandler handler = mock(MessageHandler.class);
channel.subscribe(handler);
Bar bar = ac.getBean(Bar.class);
bar.toString();
verify(handler, times(0)).handleMessage(Mockito.any(Message.class));
ac.close();
}
@Test
public void testWithServiceEquals() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
MessageHandler handler = mock(MessageHandler.class);
channel.subscribe(handler);
@@ -225,17 +242,19 @@ public class GatewayInterfaceTests {
fb.afterPropertiesSet();
assertFalse(bar.equals(fb.getObject()));
verify(handler, times(0)).handleMessage(Mockito.any(Message.class));
ac.close();
}
@Test
public void testWithServiceGetClass() {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
MessageHandler handler = mock(MessageHandler.class);
channel.subscribe(handler);
Bar bar = ac.getBean(Bar.class);
bar.getClass();
verify(handler, times(0)).handleMessage(Mockito.any(Message.class));
ac.close();
}
@Test(expected=IllegalArgumentException.class)
@@ -245,7 +264,7 @@ public class GatewayInterfaceTests {
@Test
public void testWithCustomMapper() {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
final AtomicBoolean called = new AtomicBoolean();
MessageHandler handler = new MessageHandler() {
@@ -260,11 +279,12 @@ public class GatewayInterfaceTests {
Baz baz = ac.getBean(Baz.class);
baz.baz("hello");
assertTrue(called.get());
ac.close();
}
@Test
public void testLateReply() throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
ConfigurableApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
Bar baz = ac.getBean(Bar.class);
String reply = baz.lateReply("hello");
assertNull(reply);
@@ -273,6 +293,7 @@ public class GatewayInterfaceTests {
assertNotNull(receive);
MessagingException messagingException = (MessagingException) receive.getPayload();
assertThat(messagingException.getMessage(), Matchers.startsWith("Reply message received but the receiving thread has exited due to a timeout"));
ac.close();
}